Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions src/DIRAC/FrameworkSystem/Service/ProxyManagerHandler.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
""" ProxyManager is the implementation of the ProxyManagement service in the DISET framework
"""ProxyManager is the implementation of the ProxyManagement service in the DISET framework

.. literalinclude:: ../ConfigTemplate.cfg
:start-after: ##BEGIN ProxyManager:
:end-before: ##END
:dedent: 2
:caption: ProxyManager options
.. literalinclude:: ../ConfigTemplate.cfg
:start-after: ##BEGIN ProxyManager:
:end-before: ##END
:dedent: 2
:caption: ProxyManager options
"""

from DIRAC import S_ERROR, S_OK, gLogger
from DIRAC.ConfigurationSystem.Client.Helpers import Registry
from DIRAC.Core.DISET.RequestHandler import RequestHandler, getServiceOption
Expand Down Expand Up @@ -325,6 +326,7 @@ def export_exchangeProxyForToken(self):
credDict["group"],
set(credDict.get("groupProperties", []) + credDict.get("properties", [])),
expires_minutes=credDict["secondsLeft"] // 60 + 1,
source="ProxyManager",
)


Expand Down
16 changes: 11 additions & 5 deletions src/DIRAC/FrameworkSystem/Utilities/diracx.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@
DEFAULT_TOKEN_CACHE_SIZE = 1024


def get_token(username: str, group: str, dirac_properties: set[str], *, expires_minutes: int | None = None):
"""Do a legacy exchange to get a DiracX access_token+refresh_token"""
def get_token(
username: str, group: str, dirac_properties: set[str], *, expires_minutes: int | None = None, source: str = ""
):
"""Do a legacy exchange to get a DiracX access_token+refresh_token

The source parameter only purpose is to appear in the URL on diracx logs"""
diracxUrl = gConfig.getValue("/DiracX/URL")
if not diracxUrl:
raise ValueError("Missing mandatory /DiracX/URL configuration")
Expand All @@ -44,6 +48,7 @@ def get_token(username: str, group: str, dirac_properties: set[str], *, expires_
"preferred_username": username,
"scope": " ".join(scopes),
"expires_minutes": expires_minutes,
"source": source,
},
headers={"Authorization": f"Bearer {apiKey}"},
timeout=10,
Expand All @@ -58,15 +63,15 @@ def get_token(username: str, group: str, dirac_properties: set[str], *, expires_
TTLCache(maxsize=DEFAULT_TOKEN_CACHE_SIZE, ttl=DEFAULT_TOKEN_CACHE_TTL),
key=lambda a, b, c: hashkey(a, b, *sorted(c)),
)
def _get_token_file(username: str, group: str, dirac_properties: set[str]) -> Path:
def _get_token_file(username: str, group: str, dirac_properties: set[str], *, source: str = "") -> Path:
"""Write token to a temporary file and return the path to that file"""
data = get_token(username, group, dirac_properties)
data = get_token(username, group, dirac_properties, source=source)
token_location = Path(NamedTemporaryFile().name)
write_credentials(TokenResponse(**data), location=token_location)
return token_location


def TheImpersonator(credDict: dict[str, Any]) -> SyncDiracClient:
def TheImpersonator(credDict: dict[str, Any], *, source: str = "") -> SyncDiracClient:
"""
Client to be used by DIRAC server needing to impersonate
a user for diracx.
Expand All @@ -83,6 +88,7 @@ def TheImpersonator(credDict: dict[str, Any]) -> SyncDiracClient:
credDict["username"],
credDict["group"],
set(credDict.get("groupProperties", []) + credDict.get("properties", [])),
source=source,
)
pref = DiracxPreferences(url=diracxUrl, credentials_path=token_location)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def _getFromClient(self, fileId, token, fileSize, fileHelper=None, data=""):
format=extension,
)

with TheImpersonator(credDict) as client:
with TheImpersonator(credDict, source="SandboxStore") as client:
res = client.jobs.initiate_sandbox_upload(sandbox_info)

if res.url:
Expand Down Expand Up @@ -415,7 +415,7 @@ def _sendToClient(self, fileID, token, fileHelper=None, raw=False):
# If the PFN starts with S3, we know it has been uploaded to the
# S3 sandbox store, so download it from there before sending it
if filePath.startswith("/S3"):
with TheImpersonator(credDict) as client:
with TheImpersonator(credDict, source="SandboxStore") as client:
res = client.jobs.get_sandbox_file(pfn=filePath)
r = requests.get(res.url)
r.raise_for_status()
Expand Down
4 changes: 3 additions & 1 deletion tests/CI/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ services:

# Mock of an S3 storage
s3-direct:
image: adobe/s3mock
# Fix the version until https://github.com/adobe/S3Mock/issues/2321
# is resolved
image: adobe/s3mock:3.12.0
container_name: s3-direct
hostname: s3-direct
ports:
Expand Down
Loading