Skip to content

Commit 57df1ab

Browse files
authored
Merge pull request #45780 from JanChyczynski/tier0cert_14_0_6
[14.0.X] Add certificates handling to Tier0Handler
2 parents 6277012 + 8e62041 commit 57df1ab

File tree

1 file changed

+52
-37
lines changed

1 file changed

+52
-37
lines changed

CondCore/Utilities/python/tier0.py

+52-37
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
import pycurl
1313

14-
tier0Url = 'https://cmsweb.cern.ch/t0wmadatasvc/prod/'
14+
tier0Url = os.getenv('TIER0_API_URL', 'https://cmsweb.cern.ch/t0wmadatasvc/prod/')
1515

1616
class Tier0Error(Exception):
1717
'''Tier0 exception.
@@ -23,7 +23,7 @@ def __init__(self, message):
2323

2424
def unique(seq, keepstr=True):
2525
t = type(seq)
26-
if t in (unicode, str):
26+
if t is str:
2727
t = (list, t('').join)[bool(keepstr)]
2828
try:
2929
remaining = set(seq)
@@ -90,51 +90,66 @@ def unsetDebug( self ):
9090
def setProxy( self, proxy ):
9191
self._proxy = proxy
9292

93+
def _getCerts( self ) -> str:
94+
cert_path = os.getenv('X509_USER_CERT', '')
95+
key_path = os.getenv('X509_USER_KEY', '')
96+
97+
certs = ""
98+
if cert_path:
99+
certs += f' --cert {cert_path}'
100+
else:
101+
logging.warning("No certificate provided for Tier0 access")
102+
if key_path:
103+
certs += f' --key {key_path}'
104+
return certs
105+
106+
def _curlQueryTier0( self, url:str, force_debug:bool = False, force_cert:bool = False):
107+
userAgent = "User-Agent: ConditionWebServices/1.0 python/%d.%d.%d PycURL/%s" \
108+
% ( sys.version_info[ :3 ] + ( pycurl.version_info()[ 1 ], ) )
109+
debug = "-v" if self._debug or force_debug else "-s -S"
110+
111+
proxy = f"--proxy {self._proxy}" if self._proxy else ""
112+
certs = self._getCerts() if not self._proxy or force_cert else ""
113+
114+
cmd = '/usr/bin/curl -k -L --user-agent "%s" %s --connect-timeout %i --retry %i %s %s %s' \
115+
% (userAgent, proxy, self._timeOut, self._retries, debug, url, certs)
116+
117+
# time the curl to understand if re-tries have been carried out
118+
start = time.time()
119+
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
120+
(stdoutdata, stderrdata) = process.communicate()
121+
end = time.time()
122+
return process.returncode, stdoutdata, stderrdata, end-start
123+
93124
def _queryTier0DataSvc( self, url ):
94125
"""
95126
Queries Tier0DataSvc.
96127
url: Tier0DataSvc URL.
97128
@returns: dictionary, from whence the required information must be retrieved according to the API call.
98129
Raises if connection error, bad response, or timeout after retries occur.
99130
"""
100-
101-
userAgent = "User-Agent: ConditionWebServices/1.0 python/%d.%d.%d PycURL/%s" % ( sys.version_info[ :3 ] + ( pycurl.version_info()[ 1 ], ) )
102131

103-
proxy = ""
104-
if self._proxy: proxy = ' --proxy=%s ' % self._proxy
105-
106-
debug = " -s -S "
107-
if self._debug: debug = " -v "
108-
109-
cmd = '/usr/bin/curl -k -L --user-agent "%s" %s --connect-timeout %i --retry %i %s %s ' % (userAgent, proxy, self._timeOut, self._retries, debug, url)
110-
111-
# time the curl to understand if re-tries have been carried out
112-
start = time.time()
113-
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
114-
(stdoutdata, stderrdata) = process.communicate()
115-
retcode = process.returncode
116-
end = time.time()
132+
retcode, stdoutdata, stderrdata, query_time = self._curlQueryTier0(url)
117133

118134
if retcode != 0 or stderrdata:
119-
120-
# if the first curl has failed, logg its stderror and prepare and independent retry
121-
msg = "looks like curl returned an error: retcode=%s and took %s seconds" % (retcode,(end-start),)
122-
msg += ' msg = "'+str(stderrdata)+'"'
123-
logging.error(msg)
124-
125-
time.sleep(10)
126-
cmd = '/usr/bin/curl -k -L --user-agent "%s" %s --connect-timeout %i --retry %i %s %s ' % (userAgent, proxy, self._timeOut, self._retries, "-v", url)
127-
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
128-
(stdoutdata, stderrdata) = process.communicate()
129-
retcode = process.returncode
130-
if retcode != 0:
131-
msg = "looks like curl returned an error for the second time: retcode=%s" % (retcode,)
132-
msg += ' msg = "'+str(stderrdata)+'"'
133-
logging.error(msg)
134-
raise Tier0Error(msg)
135-
else :
136-
msg = "curl returned ok upon the second try"
137-
logging.info(msg)
135+
136+
# if the first curl has failed, logg its stderror and prepare and independent retry
137+
msg = "looks like curl returned an error: retcode=%s and took %s seconds" % (retcode, query_time,)
138+
msg += ' msg = "'+str(stderrdata)+'"'
139+
logging.error(msg)
140+
if self._proxy:
141+
logging.info("before assumed proxy provides authentication, now trying with both proxy and certificate")
142+
143+
time.sleep(10)
144+
retcode, stdoutdata, stderrdata, query_time = self._curlQueryTier0(url, force_debug=True, force_cert=True)
145+
if retcode != 0:
146+
msg = "looks like curl returned an error for the second time: retcode=%s" % (retcode,)
147+
msg += ' msg = "'+str(stderrdata)+'"'
148+
logging.error(msg)
149+
raise Tier0Error(msg)
150+
else:
151+
msg = "curl returned ok upon the second try"
152+
logging.info(msg)
138153
resp = json.loads( ''.join(stdoutdata.decode()).replace( "'", '"').replace(' None', ' "None"') )
139154
return resp
140155

0 commit comments

Comments
 (0)