11#!/usr/bin/env python3
22
33import os
4+ import re
45import sys
56import time
67import getopt
78import urllib .error
89import urllib .request
9- import comanage_scripts_utils as utils
10+ import comanage_utils as utils
1011
1112
1213SCRIPT = os .path .basename (__file__ )
3334 (default = { ENDPOINT } )
3435 -o outfile specify output file (default: write to stdout)
3536 -g filter_group filter users by group name (eg, 'ap1-login')
37+ -l localmaps specify a comma-delimited list of local HTCondor mapfiles to merge into outfile
3638 -h display this help text
3739
3840PASS for USER is taken from the first of:
@@ -52,14 +54,15 @@ def usage(msg=None):
5254
5355class Options :
5456 endpoint = ENDPOINT
55- user = "co_8 .project_script"
57+ user = "co_7 .project_script"
5658 osg_co_id = OSG_CO_ID
5759 outfile = None
5860 authstr = None
5961 ldap_server = LDAP_SERVER
6062 ldap_user = LDAP_USER
6163 ldap_authtok = None
6264 filtergrp = None
65+ localmaps = []
6366
6467
6568options = Options ()
@@ -91,7 +94,8 @@ def get_co_group_members__pids(gid):
9194 #print(f"get_co_group_members__pids({gid})")
9295 resp_data = utils .get_co_group_members (gid , options .endpoint , options .authstr )
9396 data = utils .get_datalist (resp_data , "CoGroupMembers" )
94- return [ m ["Person" ]["Id" ] for m in data ]
97+ # For INF-1060: Temporary Fix until "The Great Project Provisioning" is finished
98+ return [ m ["Person" ]["Id" ] for m in data if m ["Member" ] == True ]
9599
96100
97101def get_co_person_osguser (pid ):
@@ -127,6 +131,7 @@ def parse_options(args):
127131 if op == '-e' : options .endpoint = arg
128132 if op == '-o' : options .outfile = arg
129133 if op == '-g' : options .filtergrp = arg
134+ if op == '-l' : options .localmaps = arg .split ("," )
130135
131136 try :
132137 user , passwd = utils .getpw (options .user , passfd , passfile )
@@ -135,6 +140,11 @@ def parse_options(args):
135140 except PermissionError :
136141 usage ("PASS required" )
137142
143+ def _deduplicate_list (items ):
144+ """ Deduplicate a list while maintaining order by converting it to a dictionary and then back to a list.
145+ Used to ensure a consistent ordering for output group lists, since sets are unordered.
146+ """
147+ return list (dict .fromkeys (items ))
138148
139149def get_ldap_group_members_dict ():
140150 group_data_dict = dict ()
@@ -215,6 +225,32 @@ def get_osguser_groups(filter_group_name=None):
215225 return usernames_to_project_map
216226
217227
228+ def parse_localmap (inputfile ):
229+ user_groupmap = dict ()
230+ with open (inputfile , 'r' , encoding = 'utf-8' ) as file :
231+ for line in file :
232+ # Split up 3 semantic columns
233+ split_line = line .strip ().split (maxsplit = 2 )
234+ if split_line [0 ] == "*" and len (split_line ) == 3 :
235+ line_groups = re .split (r'[ ,]+' , split_line [2 ])
236+ if split_line [1 ] in user_groupmap :
237+ user_groupmap [split_line [1 ]] = _deduplicate_list (user_groupmap [split_line [1 ]] + line_groups )
238+ else :
239+ user_groupmap [split_line [1 ]] = line_groups
240+ return user_groupmap
241+
242+
243+ def merge_maps (maps ):
244+ merged_map = dict ()
245+ for projectmap in maps :
246+ for key in projectmap .keys ():
247+ if key in merged_map :
248+ merged_map [key ] = _deduplicate_list (merged_map [key ] + projectmap [key ])
249+ else :
250+ merged_map [key ] = projectmap [key ]
251+ return merged_map
252+
253+
218254def print_usermap_to_file (osguser_groups , file ):
219255 for osguser , groups in sorted (osguser_groups .items ()):
220256 print ("* {} {}" .format (osguser , "," .join (group .strip () for group in groups )), file = file )
@@ -232,12 +268,17 @@ def main(args):
232268 parse_options (args )
233269
234270 osguser_groups = get_osguser_groups (options .filtergrp )
235- print_usermap (osguser_groups )
271+
272+ maps = [osguser_groups ]
273+ for localmap in options .localmaps :
274+ maps .append (parse_localmap (localmap ))
275+ osguser_groups_merged = merge_maps (maps )
276+
277+ print_usermap (osguser_groups_merged )
236278
237279
238280if __name__ == "__main__" :
239281 try :
240282 main (sys .argv [1 :])
241- except urllib .error .HTTPError as e :
242- print (e , file = sys .stderr )
243- sys .exit (1 )
283+ except Exception as e :
284+ sys .exit (e )
0 commit comments