11#!/usr/bin/env python3
22
3- import re
43import os
54import sys
6- import json
75import time
86import getopt
9- import subprocess
107import urllib .error
118import urllib .request
129import comanage_scripts_utils as utils
1310
1411
1512SCRIPT = os .path .basename (__file__ )
1613ENDPOINT = "https://registry-test.cilogon.org/registry/"
14+ LDAP_SERVER = "ldaps://ldap-test.cilogon.org"
15+ LDAP_USER = "uid=registry_user,ou=system,o=OSG,o=CO,dc=cilogon,dc=org"
1716OSG_CO_ID = 8
18- MINTIMEOUT = 5
19- MAXTIMEOUT = 625
20- TIMEOUTMULTIPLE = 5
2117CACHE_FILENAME = "COmanage_Projects_cache.txt"
2218CACHE_LIFETIME_HOURS = 0.5
2319
24- LDAP_AUTH_COMMAND = [
25- "awk" , "/ldap_default_authtok/ {print $3}" , "/etc/sssd/conf.d/0060_domain_CILOGON.ORG.conf" ,
26- ]
27-
28- LDAP_GROUP_MEMBERS_COMMAND = [
29- "ldapsearch" ,
30- "-H" ,
31- "ldaps://ldap.cilogon.org" ,
32- "-D" ,
33- "uid=readonly_user,ou=system,o=OSG,o=CO,dc=cilogon,dc=org" ,
34- "-w" , "{auth}" ,
35- "-b" ,
36- "ou=groups,o=OSG,o=CO,dc=cilogon,dc=org" ,
37- "-s" ,
38- "one" ,
39- "(cn=*)" ,
40- ]
41-
42- LDAP_ACTIVE_USERS_COMMAND = [
43- "ldapsearch" ,
44- "-LLL" ,
45- "-H" , "ldaps://ldap.cilogon.org" ,
46- "-D" , "uid=readonly_user,ou=system,o=OSG,o=CO,dc=cilogon,dc=org" ,
47- "-x" ,
48- "-w" , "{auth}" ,
49- "-b" , "ou=people,o=OSG,o=CO,dc=cilogon,dc=org" ,
50- "{filter}" , "voPersonApplicationUID" ,
51- "|" , "grep" , "voPersonApplicationUID" ,
52- "|" , "sort" ,
53- ]
5420
5521_usage = f"""\
5622 usage: [PASS=...] { SCRIPT } [OPTIONS]
5723
5824OPTIONS:
5925 -u USER[:PASS] specify USER and optionally PASS on command line
6026 -c OSG_CO_ID specify OSG CO ID (default = { OSG_CO_ID } )
27+ -s LDAP_SERVER specify LDAP server to read data from
28+ -l LDAP_USER specify LDAP user for reading data from LDAP server
29+ -a ldap_authfile specify path to file to open and read LDAP authtok
6130 -d passfd specify open fd to read PASS
6231 -f passfile specify path to file to open and read PASS
6332 -e ENDPOINT specify REST endpoint
@@ -87,6 +56,9 @@ class Options:
8756 osg_co_id = OSG_CO_ID
8857 outfile = None
8958 authstr = None
59+ ldap_server = LDAP_SERVER
60+ ldap_user = LDAP_USER
61+ ldap_authtok = None
9062 filtergrp = None
9163
9264
@@ -110,14 +82,14 @@ def co_group_is_project(gid):
11082
11183
11284def get_co_group_osggid (gid ):
113- resp_data = get_co_group_identifiers (gid )
114- data = get_datalist (resp_data , "Identifiers" )
85+ resp_data = utils . get_co_group_identifiers (gid , options . endpoint , options . authstr )
86+ data = utils . get_datalist (resp_data , "Identifiers" )
11587 return list (filter (lambda x : x ["Type" ] == "osggid" , data ))[0 ]["Identifier" ]
11688
11789
11890def get_co_group_osggid (gid ):
119- resp_data = get_co_group_identifiers (gid )
120- data = get_datalist (resp_data , "Identifiers" )
91+ resp_data = utils . get_co_group_identifiers (gid , options . endpoint , options . authstr )
92+ data = utils . get_datalist (resp_data , "Identifiers" )
12193 return list (filter (lambda x : x ["Type" ] == "osggid" , data ))[0 ]["Identifier" ]
12294
12395
@@ -147,11 +119,15 @@ def parse_options(args):
147119
148120 passfd = None
149121 passfile = None
122+ ldap_authfile = None
150123
151124 for op , arg in ops :
152125 if op == '-h' : usage ()
153126 if op == '-u' : options .user = arg
154127 if op == '-c' : options .osg_co_id = int (arg )
128+ if op == '-s' : options .ldap_server = arg
129+ if op == '-l' : options .ldap_user = arg
130+ if op == '-a' : ldap_authfile = arg
155131 if op == '-d' : passfd = int (arg )
156132 if op == '-f' : passfile = arg
157133 if op == '-e' : options .endpoint = arg
@@ -161,69 +137,20 @@ def parse_options(args):
161137 try :
162138 user , passwd = utils .getpw (options .user , passfd , passfile )
163139 options .authstr = utils .mkauthstr (user , passwd )
140+ options .ldap_authtok = utils .get_ldap_authtok (ldap_authfile )
164141 except PermissionError :
165142 usage ("PASS required" )
166143
167144
168- def get_ldap_group_members_data ():
169- gidNumber_str = "gidNumber: "
170- gidNumber_regex = re .compile (gidNumber_str )
171- member_str = "hasMember: "
172- member_regex = re .compile (member_str )
173-
174- auth_str = subprocess .run (
175- LDAP_AUTH_COMMAND ,
176- stdout = subprocess .PIPE
177- ).stdout .decode ('utf-8' ).strip ()
178-
179- ldap_group_members_command = LDAP_GROUP_MEMBERS_COMMAND
180- ldap_group_members_command [LDAP_GROUP_MEMBERS_COMMAND .index ("{auth}" )] = auth_str
181-
182- data_file = subprocess .run (
183- ldap_group_members_command , stdout = subprocess .PIPE ).stdout .decode ('utf-8' ).split ('\n ' )
184-
185- search_results = list (filter (
186- lambda x : not re .compile ("#|dn:|cn:|objectClass:" ).match (x ),
187- (line for line in data_file )))
188-
189- search_results .reverse ()
190-
145+ def get_ldap_group_members_dict ():
191146 group_data_dict = dict ()
192- index = 0
193- while index < len (search_results ) - 1 :
194- while not gidNumber_regex .match (search_results [index ]):
195- index += 1
196- gid = search_results [index ].replace (gidNumber_str , "" )
197- members_list = []
198- while search_results [index ] != "" :
199- if member_regex .match (search_results [index ]):
200- members_list .append (search_results [index ].replace (member_str , "" ))
201- index += 1
202- group_data_dict [gid ] = members_list
203- index += 1
147+ for group_gid in utils .get_ldap_groups (options .ldap_server , options .ldap_user , options .ldap_authtok ):
148+ group_members = utils .get_ldap_group_members (group_gid , options .ldap_server , options .ldap_user , options .ldap_authtok )
149+ group_data_dict [group_gid ] = group_members
204150
205151 return group_data_dict
206152
207153
208- def get_ldap_active_users (filter_group_name ):
209- auth_str = subprocess .run (
210- LDAP_AUTH_COMMAND ,
211- stdout = subprocess .PIPE
212- ).stdout .decode ('utf-8' ).strip ()
213-
214- filter_str = ("(isMemberOf=CO:members:active)" if filter_group_name is None
215- else f"(&(isMemberOf={ filter_group_name } )(isMemberOf=CO:members:active))" )
216-
217- ldap_active_users_command = LDAP_ACTIVE_USERS_COMMAND
218- ldap_active_users_command [LDAP_ACTIVE_USERS_COMMAND .index ("{auth}" )] = auth_str
219- ldap_active_users_command [LDAP_ACTIVE_USERS_COMMAND .index ("{filter}" )] = filter_str
220-
221- active_users = subprocess .run (ldap_active_users_command , stdout = subprocess .PIPE ).stdout .decode ('utf-8' ).split ('\n ' )
222- users = set (line .replace ("voPersonApplicationUID: " , "" ) if re .compile ("dn: voPerson*" )
223- else "" for line in active_users )
224- return users
225-
226-
227154def create_user_to_projects_map (project_to_user_map , active_users , osggids_to_names ):
228155 users_to_projects_map = dict ()
229156 for osggid in project_to_user_map :
@@ -256,26 +183,25 @@ def get_co_api_data():
256183 for entry in entries :
257184 osggid_name_pair = entry .split (":" )
258185 if len (osggid_name_pair ) == 2 :
259- project_osggids_to_name [osggid_name_pair [0 ]] = osggid_name_pair [1 ]
186+ project_osggids_to_name [int (osggid_name_pair [0 ])] = osggid_name_pair [1 ].strip ()
187+ r .close ()
260188 else :
189+ r .close ()
261190 raise OSError
262191 except OSError :
263192 with open (CACHE_FILENAME , "w" ) as w :
264193 project_osggids_to_name = get_groups_data_from_api ()
265194 print (time .time (), file = w )
266195 for osggid , name in project_osggids_to_name .items ():
267196 print (f"{ osggid } :{ name } " , file = w )
268- finally :
269- if r :
270- r .close ()
271197
272198 return project_osggids_to_name
273199
274200
275201def get_osguser_groups (filter_group_name = None ):
276202 project_osggids_to_name = get_co_api_data ()
277- ldap_groups_members = get_ldap_group_members_data ()
278- ldap_users = get_ldap_active_users (filter_group_name )
203+ ldap_groups_members = get_ldap_group_members_dict ()
204+ ldap_users = utils . get_ldap_active_users (options . ldap_server , options . ldap_user , options . ldap_authtok , filter_group_name )
279205
280206 active_project_osggids = set (ldap_groups_members .keys ()).intersection (set (project_osggids_to_name .keys ()))
281207 project_to_user_map = {
0 commit comments