From 67dd950b256d86f0c6f5524f339862a0cb1d93e3 Mon Sep 17 00:00:00 2001 From: olloz26 Date: Wed, 4 Dec 2024 11:26:10 +0100 Subject: [PATCH] feat: convert openBIS cloud storage configurations into valid rclone configurations before starting a session --- .../notebooks/api/schemas/cloud_storage.py | 16 ++++++++++++---- components/renku_data_services/storage/rclone.py | 11 ++++++++--- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/components/renku_data_services/notebooks/api/schemas/cloud_storage.py b/components/renku_data_services/notebooks/api/schemas/cloud_storage.py index 2c1dc4977..0991cb71b 100644 --- a/components/renku_data_services/notebooks/api/schemas/cloud_storage.py +++ b/components/renku_data_services/notebooks/api/schemas/cloud_storage.py @@ -210,16 +210,24 @@ def get_manifest_patch( return patches def config_string(self, name: str) -> str: - """Convert configuration oblect to string representation. + """Convert configuration object to string representation. Needed to create RClone compatible INI files. """ if not self.configuration: raise ValidationError("Missing configuration for cloud storage") - if self.configuration["type"] == "s3" and self.configuration.get("provider", None) == "Switch": + # TODO Use RCloneValidator.get_real_configuration(...) instead. + real_config = dict(self.configuration) + if real_config["type"] == "s3" and real_config.get("provider") == "Switch": # Switch is a fake provider we add for users, we need to replace it since rclone itself # doesn't know it - self.configuration["provider"] = "Other" + real_config["provider"] = "Other" + elif real_config["type"] == "openbis": + real_config["type"] = "sftp" + real_config["port"] = "2222" + real_config["user"] = "?" + real_config["pass"] = real_config.pop("session_token") + parser = ConfigParser() parser.add_section(name) @@ -228,7 +236,7 @@ def _stringify(value: Any) -> str: return "true" if value else "false" return str(value) - for k, v in self.configuration.items(): + for k, v in real_config.items(): parser.set(name, k, _stringify(v)) stringio = StringIO() parser.write(stringio) diff --git a/components/renku_data_services/storage/rclone.py b/components/renku_data_services/storage/rclone.py index 53719647a..1eb013267 100644 --- a/components/renku_data_services/storage/rclone.py +++ b/components/renku_data_services/storage/rclone.py @@ -246,10 +246,15 @@ def validate_sensitive_data( continue raise errors.ValidationError(message=f"The '{key}' property is not marked as sensitive.") - def get_real_config(self, configuration: Union["RCloneConfig", dict[str, Any]]) -> dict[str, Any]: + def get_real_configuration(self, configuration: Union["RCloneConfig", dict[str, Any]]) -> dict[str, Any]: """Converts a Renku rclone configuration to a real rclone config.""" real_config = dict(configuration) - if configuration["type"] == "openbis": + + if real_config["type"] == "s3" and real_config.get("provider") == "Switch": + # Switch is a fake provider we add for users, we need to replace it since rclone itself + # doesn't know it + real_config["provider"] = "Other" + elif configuration["type"] == "openbis": real_config["type"] = "sftp" real_config["port"] = "2222" real_config["user"] = "?" @@ -265,7 +270,7 @@ async def test_connection( except errors.ValidationError as e: return ConnectionResult(False, str(e)) - obscured_rclone_config = await self.obscure_config(self.get_real_config(configuration)) + obscured_rclone_config = await self.obscure_config(self.get_real_configuration(configuration)) with tempfile.NamedTemporaryFile(mode="w+", delete=False, encoding="utf-8") as f: obscured_rclone_config_string = "\n".join(f"{k}={v}" for k, v in obscured_rclone_config.items())