1111
1212import pycurl
1313
14- tier0Url = ' https://cmsweb.cern.ch/t0wmadatasvc/prod/'
14+ tier0Url = os . getenv ( 'TIER0_API_URL' , ' https://cmsweb.cern.ch/t0wmadatasvc/prod/')
1515
1616class Tier0Error (Exception ):
1717 '''Tier0 exception.
@@ -23,7 +23,7 @@ def __init__(self, message):
2323
2424def 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