@@ -54,6 +54,7 @@ def __init__(self, caller_options):
5454 'remove_strays' : False ,
5555 'stray_list_input_path' : None ,
5656 'stray_list_output_path' : None ,
57+ 'test_mode' : False ,
5758 'update_user_info' : True ,
5859 'username_filter_regex' : None ,
5960 }
@@ -89,22 +90,24 @@ def __init__(self, caller_options):
8990 # of primary-umapi users, who are presumed to be in primary-umapi domains.
9091 # So instead of keeping track of excluded users in the primary umapi,
9192 # we keep track of included users, so we can match them against users
92- # in the secondary umapis (and exclude all that don't match).
93+ # in the secondary umapis (and exclude all that don't match). Finally,
94+ # we keep track of user keys (in any umapi) that we have updated, so
95+ # we can correctly report their count.
9396 self .included_user_keys = set ()
9497 self .excluded_user_count = 0
98+ self .updated_user_keys = set ()
9599
96100 # stray key input path comes in, stray_list_output_path goes out
97101 self .stray_key_map = self .make_stray_key_map ()
98102 if options ['stray_list_input_path' ]:
99103 self .read_stray_key_map (options ['stray_list_input_path' ])
100104 self .stray_list_output_path = options ['stray_list_output_path' ]
101105
102- # determine whether we need to process strays at all
103- self .will_process_strays = (not options ['exclude_strays' ]) and (options ['manage_groups' ] or
104- options ['stray_list_output_path' ] or
105- options ['disentitle_strays' ] or
106- options ['remove_strays' ] or
107- options ['delete_strays' ])
106+ # determine what processing is needed on strays
107+ self .will_manage_strays = (options ['manage_groups' ] or options ['disentitle_strays' ] or
108+ options ['remove_strays' ] or options ['delete_strays' ])
109+ self .will_process_strays = (not options ['exclude_strays' ]) and (options ['stray_list_output_path' ] or
110+ self .will_manage_strays )
108111
109112 # in/out variables for per-user after-mapping-hook code
110113 self .after_mapping_hook_scope = {
@@ -171,6 +174,7 @@ def log_action_summary(self, umapi_connectors):
171174 # find the total number of adobe users and excluded users
172175 self .action_summary ['adobe_users_read' ] = len (self .included_user_keys ) + self .excluded_user_count
173176 self .action_summary ['adobe_users_excluded' ] = self .excluded_user_count
177+ self .action_summary ['adobe_users_updated' ] = len (self .updated_user_keys )
174178 # find out the number of users that have no changes; this depends on whether
175179 # we actually read the directory or read an input file. So there are two cases:
176180 if self .action_summary ['adobe_users_read' ] == 0 :
@@ -182,7 +186,11 @@ def log_action_summary(self, umapi_connectors):
182186 self .action_summary ['adobe_users_updated' ] -
183187 self .action_summary ['adobe_strays_processed' ]
184188 )
185- logger .info ('---------------------------------- Action Summary ----------------------------------' )
189+ if self .options ['test_mode' ]:
190+ header = '- Action Summary (TEST MODE) -'
191+ else :
192+ header = '------- Action Summary -------'
193+ logger .info ('---------------------------' + header + '---------------------------' )
186194
187195 # English text description for action summary log.
188196 # The action summary will be shown the same order as they are defined in this list
@@ -193,7 +201,7 @@ def log_action_summary(self, umapi_connectors):
193201 ['adobe_users_excluded' , 'Number of Adobe users excluded from updates' ],
194202 ['adobe_users_unchanged' , 'Number of non-excluded Adobe users with no changes' ],
195203 ['adobe_users_created' , 'Number of new Adobe users added' ],
196- ['adobe_users_updated' , 'Number of existing Adobe users updated' ],
204+ ['adobe_users_updated' , 'Number of matching Adobe users updated' ],
197205 ]
198206 if self .will_process_strays :
199207 if self .options ['delete_strays' ]:
@@ -204,7 +212,7 @@ def log_action_summary(self, umapi_connectors):
204212 action = 'removed from all groups'
205213 else :
206214 action = 'with groups processed'
207- action_summary_description .append (['adobe_strays_processed' , 'Number of Adobe-only users ' + action + ':' ])
215+ action_summary_description .append (['adobe_strays_processed' , 'Number of Adobe-only users ' + action ])
208216
209217 # prepare the network summary
210218 umapi_summary_format = 'Number of%s%s UMAPI actions sent (total, success, error)'
@@ -436,15 +444,16 @@ def process_strays(self, umapi_connectors):
436444 stray_count = len (self .get_stray_keys ())
437445 if self .stray_list_output_path :
438446 self .write_stray_key_map ()
439- max_missing = self .options ['max_adobe_only_users' ]
440- if stray_count > max_missing :
441- self .logger .critical ('Unable to process Adobe-only users, as their count (%s) is larger '
442- 'than the max_adobe_only_users setting (%d)' , stray_count , max_missing )
443- self .action_summary ['adobe_strays_processed' ] = 0
444- return
445- self .action_summary ['adobe_strays_processed' ] = stray_count
446- self .logger .debug ("Processing Adobe-only users..." )
447- self .manage_strays (umapi_connectors )
447+ if self .will_manage_strays :
448+ max_missing = self .options ['max_adobe_only_users' ]
449+ if stray_count > max_missing :
450+ self .logger .critical ('Unable to process Adobe-only users, as their count (%s) is larger '
451+ 'than the max_adobe_only_users setting (%d)' , stray_count , max_missing )
452+ self .action_summary ['adobe_strays_processed' ] = 0
453+ return
454+ self .action_summary ['adobe_strays_processed' ] = stray_count
455+ self .logger .debug ("Processing Adobe-only users..." )
456+ self .manage_strays (umapi_connectors )
448457
449458 def manage_strays (self , umapi_connectors ):
450459 '''
@@ -627,7 +636,7 @@ def update_umapi_user(self, umapi_info, user_key, umapi_connector,
627636 '''
628637 is_primary_org = umapi_info .get_name () == PRIMARY_UMAPI_NAME
629638 if attributes_to_update or groups_to_add or groups_to_remove :
630- self .action_summary [ 'adobe_users_updated' ] += 1 if is_primary_org else 0
639+ self .updated_user_keys . add ( user_key )
631640 if attributes_to_update :
632641 self .logger .info ('Updating info for user key: %s changes: %s' , user_key , attributes_to_update )
633642 if groups_to_add or groups_to_remove :
@@ -900,59 +909,68 @@ def read_stray_key_map(self, file_path, delimiter = None):
900909 id_type_column_name = 'type'
901910 user_column_name = 'username'
902911 domain_column_name = 'domain'
903- org_name_column_name = 'umapi'
912+ ummapi_name_column_name = 'umapi'
904913 rows = user_sync .helper .iter_csv_rows (file_path ,
905914 delimiter = delimiter ,
906915 recognized_column_names = [
907916 id_type_column_name , user_column_name , domain_column_name ,
908- org_name_column_name ,
917+ ummapi_name_column_name ,
909918 ],
910919 logger = self .logger )
911920 for row in rows :
912- org_name = row .get (org_name_column_name ) or PRIMARY_UMAPI_NAME
921+ umapi_name = row .get (ummapi_name_column_name ) or PRIMARY_UMAPI_NAME
913922 id_type = row .get (id_type_column_name )
914923 user = row .get (user_column_name )
915924 domain = row .get (domain_column_name )
916925 user_key = self .get_user_key (id_type , user , domain )
917926 if user_key :
918- self .add_stray (org_name , None )
919- self .add_stray (org_name , user_key )
927+ self .add_stray (umapi_name , None )
928+ self .add_stray (umapi_name , user_key )
920929 else :
921930 self .logger .error ("Invalid input line, ignored: %s" , row )
922931 user_count = len (self .get_stray_keys ())
923932 user_plural = "" if user_count == 1 else "s"
924- org_count = len (self .stray_key_map ) - 1
925- org_plural = "" if org_count == 1 else "s"
926- if org_count > 0 :
933+ secondary_count = len (self .stray_key_map ) - 1
934+ if secondary_count > 0 :
935+ umapi_plural = "" if secondary_count == 1 else "s"
927936 self .logger .info ('Read %d Adobe-only user%s for primary umapi, with %d secondary umapi%s' ,
928- user_count , user_plural , org_count , org_plural )
937+ user_count , user_plural , secondary_count , umapi_plural )
929938 else :
930939 self .logger .info ('Read %d Adobe-only user%s.' , user_count , user_plural )
931940
932941 def write_stray_key_map (self ):
933942 file_path = self .stray_list_output_path
934943 logger = self .logger
935944 logger .info ('Writing Adobe-only users to: %s' , file_path )
945+ # figure out if we should include a umapi column
946+ secondary_count = 0
947+ fieldnames = ['type' , 'username' , 'domain' ]
948+ for umapi_name in self .stray_key_map :
949+ if umapi_name != PRIMARY_UMAPI_NAME and self .get_stray_keys (umapi_name ):
950+ if not secondary_count :
951+ fieldnames .append ('umapi' )
952+ secondary_count += 1
936953 with open (file_path , 'wb' ) as output_file :
937954 delimiter = user_sync .helper .guess_delimiter_from_filename (file_path )
938- writer = csv .DictWriter (output_file ,
939- fieldnames = ['type' , 'username' , 'domain' , 'umapi' ],
940- delimiter = delimiter )
955+ writer = csv .DictWriter (output_file , fieldnames = fieldnames , delimiter = delimiter )
941956 writer .writeheader ()
942957 # None sorts before strings, so sorting the keys in the map
943958 # puts the primary umapi first in the output, which is handy
944- for org_name in sorted (self .stray_key_map .keys ()):
945- for user_key in self .get_stray_keys (org_name ):
959+ for umapi_name in sorted (self .stray_key_map .keys ()):
960+ for user_key in self .get_stray_keys (umapi_name ):
946961 id_type , username , domain = self .parse_user_key (user_key )
947- umapi = org_name if org_name else ""
948- writer .writerow ({'type' : id_type , 'username' : username , 'domain' : domain , 'umapi' : umapi })
962+ umapi = umapi_name if umapi_name else ""
963+ if secondary_count :
964+ row_dict = {'type' : id_type , 'username' : username , 'domain' : domain , 'umapi' : umapi }
965+ else :
966+ row_dict = {'type' : id_type , 'username' : username , 'domain' : domain }
967+ writer .writerow (row_dict )
949968 user_count = len (self .stray_key_map .get (PRIMARY_UMAPI_NAME , []))
950969 user_plural = "" if user_count == 1 else "s"
951- org_count = len (self .stray_key_map ) - 1
952- org_plural = "" if org_count == 1 else "s"
953- if org_count > 0 :
970+ if secondary_count > 0 :
971+ umapi_plural = "" if secondary_count == 1 else "s"
954972 logger .info ('Wrote %d Adobe-only user%s for primary umapi, with %d secondary umapi%s' ,
955- user_count , user_plural , org_count , org_plural )
973+ user_count , user_plural , secondary_count , umapi_plural )
956974 else :
957975 logger .info ('Wrote %d Adobe-only user%s.' , user_count , user_plural )
958976
0 commit comments