Skip to content

Commit 50503e2

Browse files
committed
fix: proxy renewal taking into account multiVOs
1 parent 26f2f23 commit 50503e2

File tree

1 file changed

+79
-39
lines changed

1 file changed

+79
-39
lines changed

src/DIRAC/Resources/Computing/AREXComputingElement.py

Lines changed: 79 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,6 @@ def __init__(self, ceUniqueID):
4646
self.restVersion = "1.0"
4747
# Time left before proxy renewal: 3 hours is a good default
4848
self.proxyTimeLeftBeforeRenewal = 10800
49-
# Current delegation ID, generated/fetched in submitJob(), renewed in getJobStatus()
50-
self._delegationID = None
5149
# Timeout
5250
self.timeout = 5.0
5351
# Request session
@@ -187,6 +185,10 @@ def _checkSession(self):
187185
self.headers.pop("Authorization", None)
188186

189187
# Get a proxy: still mandatory, even if tokens are used to authenticate
188+
if not self.proxy:
189+
self.log.error("Proxy not set")
190+
return S_ERROR("Proxy not set")
191+
190192
result = self._prepareProxy()
191193
if not result["OK"]:
192194
self.log.error("Failed to set up proxy", result["Message"])
@@ -198,7 +200,7 @@ def _checkSession(self):
198200
return S_OK()
199201

200202
# Attach the proxy to the session, only if the token is unavailable
201-
self.session.cert = Locations.getProxyLocation()
203+
self.session.cert = os.environ["X509_USER_PROXY"]
202204
return S_OK()
203205

204206
#############################################################################
@@ -241,15 +243,8 @@ def __uploadCertificate(self, delegationID, csrContent):
241243
headers = {"Content-Type": "x-pem-file"}
242244
query = self._urlJoin(os.path.join("delegations", delegationID))
243245

244-
# Get a proxy and sign the CSR
245-
proxy = X509Chain()
246-
proxyFile = Locations.getProxyLocation()
247-
if not proxyFile:
248-
return S_ERROR(f"No proxy available")
249-
result = proxy.loadProxyFromFile(proxyFile)
250-
if not result["OK"]:
251-
return S_ERROR(f"Can't load {proxyFile}: {result['Message']}")
252-
result = proxy.generateChainFromRequestString(csrContent)
246+
# Sign the CSR
247+
result = self.proxy.generateChainFromRequestString(csrContent)
253248
if not result["OK"]:
254249
self.log.error("Problem with the Certificate Signing Request:", result["Message"])
255250
return S_ERROR("Problem with the Certificate Signing Request")
@@ -322,6 +317,29 @@ def _getDelegationIDs(self):
322317
delegationIDs = [delegationContent["id"] for delegationContent in delegations]
323318
return S_OK(delegationIDs)
324319

320+
def _getProxyFromDelegationID(self, delegationID):
321+
"""Get proxy stored within the"""
322+
query = self._urlJoin(os.path.join("delegations", delegationID))
323+
params = {"action": "get"}
324+
325+
# Submit the POST request to get the delegation
326+
result = self._request("post", query, params=params)
327+
if not result["OK"]:
328+
self.log.error("Issue while interacting with the delegations.", result["Message"])
329+
return S_ERROR("Issue while interacting with the delegations")
330+
response = result["Value"]
331+
332+
proxyContent = response.text
333+
proxy = X509Chain()
334+
result = proxy.loadChainFromString(proxyContent)
335+
if not result["OK"]:
336+
self.log.error(
337+
"Issue while trying to load proxy content from delegation", f"{delegationID}: {result['Message']}"
338+
)
339+
return S_ERROR("Issue while trying to load proxy content from delegation")
340+
341+
return S_OK(proxy)
342+
325343
#############################################################################
326344

327345
def _getArcJobID(self, executableFile, inputs, outputs, delegation):
@@ -406,18 +424,33 @@ def submitJob(self, executableFile, proxy, numberOfJobs=1, inputs=None, outputs=
406424
if not result["OK"]:
407425
self.log.error("Could not get delegation IDs.", result["Message"])
408426
return S_ERROR("Could not get delegation IDs")
409-
410427
delegationIDs = result["Value"]
411-
if not delegationIDs:
428+
429+
# Get the delegationID which corresponds to the DIRAC group of the proxy if it exists
430+
currentDelegationID = None
431+
proxyGroup = self.proxy.getDIRACGroup()
432+
for delegationID in delegationIDs:
433+
# Get the proxy attached to the delegationID
434+
result = self._getProxyFromDelegationID(delegationID)
435+
if not result["OK"]:
436+
return result
437+
proxy = result["Value"]
438+
439+
if proxy.getDIRACGroup() != proxyGroup:
440+
continue
441+
442+
# If we are here, we have found the right delegationID to use
443+
currentDelegationID = delegationID
444+
445+
if not currentDelegationID:
412446
# No existing delegation, we need to prepare one
413447
result = self._prepareDelegation()
414448
if not result["OK"]:
415449
self.log.warn("Could not get a new delegation", f"for CE {self.ceHost}")
416450
return S_ERROR("Could not get a new delegation")
417-
self._delegationID = result["Value"]
418-
else:
419-
self._delegationID = delegationIDs[0]
420-
delegation = f"\n(delegationid={self._delegationID})"
451+
currentDelegationID = result["Value"]
452+
453+
delegation = f"\n(delegationid={currentDelegationID})"
421454

422455
if not inputs:
423456
inputs = []
@@ -599,33 +632,36 @@ def getCEStatus(self):
599632

600633
#############################################################################
601634

602-
def _renewDelegation(self):
603-
"""Renew the delegations"""
635+
def _renewDelegation(self, delegationID):
636+
"""Renew the delegation
637+
638+
:params delegationID: delegation ID to renew
639+
"""
604640
# Prepare the command
605641
params = {"action": "get"}
606-
query = self._urlJoin(os.path.join("delegations", self._delegationID))
642+
query = self._urlJoin(os.path.join("delegations", delegationID))
607643

608644
# Submit the POST request to get the proxy
609645
result = self._request("post", query, params=params)
610646
if not result["OK"]:
611-
self.log.error("Could not get a proxy for", f"delegation {self._delegationID}: {result['Message']}")
612-
return S_ERROR(f"Could not get a proxy for delegation {self._delegationID}")
647+
self.log.error("Could not get a proxy for", f"delegation {delegationID}: {result['Message']}")
648+
return S_ERROR(f"Could not get a proxy for delegation {delegationID}")
613649
response = result["Value"]
614650

615651
proxy = X509Chain()
616652
result = proxy.loadChainFromString(response.text)
617653
if not result["OK"]:
618-
self.log.error("Could not load proxy for", f"delegation {self._delegationID}: {result['Message']}")
619-
return S_ERROR(f"Could not load proxy for delegation {self._delegationID}")
654+
self.log.error("Could not load proxy for", f"delegation {delegationID}: {result['Message']}")
655+
return S_ERROR(f"Could not load proxy for delegation {delegationID}")
620656

621657
# Now test and renew the proxy
622658
result = proxy.getRemainingSecs()
623659
if not result["OK"]:
624660
self.log.error(
625661
"Could not get remaining time from the proxy for",
626-
f"delegation {self._delegationID}: {result['Message']}",
662+
f"delegation {delegationID}: {result['Message']}",
627663
)
628-
return S_ERROR(f"Could not get remaining time from the proxy for delegation {self._delegationID}")
664+
return S_ERROR(f"Could not get remaining time from the proxy for delegation {delegationID}")
629665
timeLeft = result["Value"]
630666

631667
if timeLeft >= self.proxyTimeLeftBeforeRenewal:
@@ -634,31 +670,31 @@ def _renewDelegation(self):
634670

635671
self.log.verbose(
636672
"Renewing delegation",
637-
f"{self._delegationID} whose proxy expires at {timeLeft}",
673+
f"{delegationID} whose proxy expires at {timeLeft}",
638674
)
639675
# Proxy needs to be renewed - try to renew it
640676
# First, get a new CSR from the delegation
641677
params = {"action": "renew"}
642-
query = self._urlJoin(os.path.join("delegations", self._delegationID))
678+
query = self._urlJoin(os.path.join("delegations", delegationID))
643679
result = self._request("post", query, params=params)
644680
if not result["OK"]:
645681
self.log.error(
646682
"Proxy not renewed, failed to get CSR",
647-
f"for delegation {self._delegationID}",
683+
f"for delegation {delegationID}",
648684
)
649-
return S_ERROR(f"Proxy not renewed, failed to get CSR for delegation {self._delegationID}")
685+
return S_ERROR(f"Proxy not renewed, failed to get CSR for delegation {delegationID}")
650686
response = result["Value"]
651687

652688
# Then, sign and upload the certificate
653-
result = self.__uploadCertificate(self._delegationID, response.text)
689+
result = self.__uploadCertificate(delegationID, response.text)
654690
if not result["OK"]:
655691
self.log.error(
656692
"Proxy not renewed, failed to send renewed proxy",
657-
f"delegation {self._delegationID}: {result['Message']}",
693+
f"delegation {delegationID}: {result['Message']}",
658694
)
659-
return S_ERROR(f"Proxy not renewed, failed to send renewed proxy for delegation {self._delegationID}")
695+
return S_ERROR(f"Proxy not renewed, failed to send renewed proxy for delegation {delegationID}")
660696

661-
self.log.verbose("Proxy successfully renewed", f"for delegation {self._delegationID}")
697+
self.log.verbose("Proxy successfully renewed", f"for delegation {delegationID}")
662698

663699
return S_OK()
664700

@@ -714,12 +750,16 @@ def getJobStatus(self, jobIDList):
714750
jobsToCancel.append(arcJob["id"])
715751
self.log.debug(f"Killing held job {jobID}")
716752

717-
# Renew delegation to renew the proxies of the jobs
718-
if self._delegationID:
719-
result = self._renewDelegation()
753+
# Renew delegations to renew the proxies of the jobs
754+
result = self._getDelegationIDs()
755+
if not result["OK"]:
756+
return result
757+
delegationIDs = result["Value"]
758+
for delegationID in delegationIDs:
759+
result = self._renewDelegation(delegationID)
720760
if not result["OK"]:
721761
# Only log here as we still want to return statuses
722-
self.log.warn("Failed to renew delegation", f"{self._delegationID}: {result['Message']}")
762+
self.log.warn("Failed to renew delegation", f"{delegationID}: {result['Message']}")
723763

724764
# Kill held jobs
725765
if jobsToCancel:

0 commit comments

Comments
 (0)