Skip to content

Commit e3677da

Browse files
committed
Query COManage to preserve ordering of groups with old behavior
1 parent 8c9a033 commit e3677da

File tree

1 file changed

+13
-67
lines changed

1 file changed

+13
-67
lines changed

osg-comanage-project-usermap.py

Lines changed: 13 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
-o outfile specify output file (default: write to stdout)
3838
-g filter_group filter users by group name (eg, 'ap1-login')
3939
-m localmaps specify a comma-delimited list of local HTCondor mapfiles to merge into outfile
40+
-n min_users Specify minimum number of users required to update the output file (default: 100)
4041
-h display this help text
4142
4243
PASS for USER is taken from the first of:
@@ -64,6 +65,7 @@ class Options:
6465
ldap_user = LDAP_USER
6566
ldap_authtok = None
6667
filtergrp = None
68+
min_users = 100 # Bail out before updating the file if we have fewer than this many users
6769
localmaps = []
6870

6971

@@ -76,41 +78,12 @@ def get_osg_co_groups__map():
7678
#print("get_osg_co_groups__map()")
7779
resp_data = utils.get_osg_co_groups(options.osg_co_id, options.endpoint, options.authstr)
7880
data = utils.get_datalist(resp_data, "CoGroups")
79-
return { g["Id"]: g["Name"] for g in data }
80-
81-
82-
def co_group_is_project(gid):
83-
#print(f"co_group_is_ospool({gid})")
84-
resp_data = utils.get_co_group_identifiers(gid, options.endpoint, options.authstr)
85-
data = utils.get_datalist(resp_data, "Identifiers")
86-
return any( i["Type"] == "ospoolproject" for i in data )
87-
88-
89-
def get_co_group_osggid(gid):
90-
resp_data = utils.get_co_group_identifiers(gid, options.endpoint, options.authstr)
91-
data = utils.get_datalist(resp_data, "Identifiers")
92-
return list(filter(lambda x : x["Type"] == "osggid", data))[0]["Identifier"]
93-
94-
95-
def get_co_group_members__pids(gid):
96-
#print(f"get_co_group_members__pids({gid})")
97-
resp_data = utils.get_co_group_members(gid, options.endpoint, options.authstr)
98-
data = utils.get_datalist(resp_data, "CoGroupMembers")
99-
# For INF-1060: Temporary Fix until "The Great Project Provisioning" is finished
100-
return [ m["Person"]["Id"] for m in data if m["Member"] == True]
101-
102-
103-
def get_co_person_osguser(pid):
104-
#print(f"get_co_person_osguser({pid})")
105-
resp_data = utils.get_co_person_identifiers(pid, options.endpoint, options.authstr)
106-
data = utils.get_datalist(resp_data, "Identifiers")
107-
typemap = { i["Type"]: i["Identifier"] for i in data }
108-
return typemap.get("osguser")
81+
return { g["Name"]: g["Id"] for g in data }
10982

11083

11184
def parse_options(args):
11285
try:
113-
ops, args = getopt.getopt(args, 'u:c:s:l:a:d:f:g:e:o:h')
86+
ops, args = getopt.getopt(args, 'u:c:s:l:a:d:f:g:e:o:h:n:m')
11487
except getopt.GetoptError:
11588
usage()
11689

@@ -133,7 +106,8 @@ def parse_options(args):
133106
if op == '-e': options.endpoint = arg
134107
if op == '-o': options.outfile = arg
135108
if op == '-g': options.filtergrp = arg
136-
if op == '-m': options.localmaps = arg.split(",")
109+
if op == '-m': options.localmaps = arg.split(",")
110+
if op == '-n': options.min_users = int(arg)
137111

138112
try:
139113
user, passwd = utils.getpw(options.user, passfd, passfile)
@@ -170,46 +144,15 @@ def create_user_to_projects_map(project_to_user_map, active_users, osggids_to_na
170144
return users_to_projects_map
171145

172146

173-
def get_groups_data_from_api():
174-
groups = get_osg_co_groups__map()
175-
project_osggids_to_name = dict()
176-
for id,name in groups.items():
177-
if co_group_is_project(id):
178-
project_osggids_to_name[get_co_group_osggid(id)] = name
179-
return project_osggids_to_name
180-
181-
182-
def get_co_api_data():
183-
try:
184-
r = open(CACHE_FILENAME, "r")
185-
lines = r.readlines()
186-
if float(lines[0]) >= (time.time() - (60 * 60 * CACHE_LIFETIME_HOURS)):
187-
entries = lines[1:len(lines)]
188-
project_osggids_to_name = dict()
189-
for entry in entries:
190-
osggid_name_pair = entry.split(":")
191-
if len(osggid_name_pair) == 2:
192-
project_osggids_to_name[int(osggid_name_pair[0])] = osggid_name_pair[1].strip()
193-
r.close()
194-
else:
195-
r.close()
196-
raise OSError
197-
except OSError:
198-
with open(CACHE_FILENAME, "w") as w:
199-
project_osggids_to_name = get_groups_data_from_api()
200-
print(time.time(), file=w)
201-
for osggid, name in project_osggids_to_name.items():
202-
print(f"{osggid}:{name}", file=w)
203-
204-
return project_osggids_to_name
205-
206-
207147
def get_osguser_groups(filter_group_name=None):
208148
ldap_users = utils.get_ldap_active_users_and_groups(options.ldap_server, options.ldap_user, options.ldap_authtok, filter_group_name)
209149
topology_projects = requests.get(f"{TOPOLOGY_ENDPOINT}/miscproject/json").json()
210150
project_names = topology_projects.keys()
151+
152+
# Get COManage group IDs to preserve ordering from pre-LDAP migration script behavior
153+
groups_ids = get_osg_co_groups__map()
211154
return {
212-
user: [g for g in groups if g in project_names]
155+
user: sorted([g for g in groups if g in project_names], key = lambda g: groups_ids.get(g, 0))
213156
for user, groups in ldap_users.items()
214157
if any(g in project_names for g in groups)
215158
and any(':members:active' in g for g in groups)
@@ -265,6 +208,9 @@ def main(args):
265208
maps.append(parse_localmap(localmap))
266209
osguser_groups_merged = merge_maps(maps)
267210

211+
# Sanity check, confirm we have generated a "sane" amount of user -> group mappings
212+
if len(osguser_groups_merged) < options.min_users:
213+
raise RuntimeError(f"Refusing to update output file: only {len(osguser_groups_merged)} users found")
268214
print_usermap(osguser_groups_merged)
269215

270216

0 commit comments

Comments
 (0)