diff --git a/dvc/config_schema.py b/dvc/config_schema.py index 19bec8d1d7..abfd7c34c4 100644 --- a/dvc/config_schema.py +++ b/dvc/config_schema.py @@ -145,7 +145,7 @@ class RelPath(str): "session_token": str, Optional("listobjects", default=False): Bool, # obsoleted Optional("use_ssl", default=True): Bool, - Optional("ssl_verify", default=True): Bool, + "ssl_verify": Any(Bool, str), "sse": str, "sse_kms_key_id": str, "acl": str, diff --git a/dvc/fs/s3.py b/dvc/fs/s3.py index 0a6b6165cd..b14f750802 100644 --- a/dvc/fs/s3.py +++ b/dvc/fs/s3.py @@ -102,7 +102,7 @@ def _prepare_credentials(self, **config): client = login_info["client_kwargs"] client["region_name"] = config.get("region") client["endpoint_url"] = config.get("endpointurl") - client["verify"] = config.get("ssl_verify", True) + client["verify"] = config.get("ssl_verify") # encryptions additional = login_info["s3_additional_kwargs"] diff --git a/tests/unit/fs/test_s3.py b/tests/unit/fs/test_s3.py index ec323753bf..cccdfc1bf0 100644 --- a/tests/unit/fs/test_s3.py +++ b/tests/unit/fs/test_s3.py @@ -39,7 +39,15 @@ def test_verify_ssl_default_param(dvc): } fs = S3FileSystem(**config) - assert fs.fs_args["client_kwargs"]["verify"] + assert "client_kwargs" not in fs.fs_args + + config = { + "url": url, + "endpointurl": "https://my.custom.s3:1234", + } + fs = S3FileSystem(**config) + + assert "verify" not in fs.fs_args["client_kwargs"] def test_s3_config_credentialpath(dvc, monkeypatch): @@ -74,6 +82,29 @@ def test_ssl_verify_bool_param(dvc): assert fs.fs_args["client_kwargs"]["verify"] == config["ssl_verify"] +def test_ssl_verify_path_param(dvc): + config = {"url": url, "ssl_verify": "/path/to/custom/cabundle.pem"} + fs = S3FileSystem(**config) + + assert fs.fs_args["client_kwargs"]["verify"] == config["ssl_verify"] + + +def test_ssl_verify_none_param(dvc): + config = {"url": url, "ssl_verify": None} + fs = S3FileSystem(**config) + + assert "client_kwargs" not in fs.fs_args + + config = { + "url": url, + "endpointurl": "https://my.custom.s3:1234", + "ssl_verify": None, + } + fs = S3FileSystem(**config) + + assert "verify" not in fs.fs_args["client_kwargs"] + + def test_grants(dvc): config = { "url": url, diff --git a/tests/unit/test_config.py b/tests/unit/test_config.py index 4e8164f4ba..a12a9992e8 100644 --- a/tests/unit/test_config.py +++ b/tests/unit/test_config.py @@ -1,4 +1,5 @@ import os +import textwrap import pytest @@ -33,3 +34,39 @@ def test_get_fs(tmp_dir, scm): assert config._get_fs("local") == config.wfs assert config._get_fs("global") == config.wfs assert config._get_fs("system") == config.wfs + + +def test_s3_ssl_verify(tmp_dir, dvc): + config = Config(validate=False) + with config.edit() as conf: + conf["remote"]["remote-name"] = {"url": "s3://bucket/dvc"} + + assert "ssl_verify" not in config["remote"]["remote-name"] + + with config.edit() as conf: + section = conf["remote"]["remote-name"] + section["ssl_verify"] = False + + assert (tmp_dir / ".dvc" / "config").read_text() == textwrap.dedent( + """\ + [core] + no_scm = True + ['remote "remote-name"'] + url = s3://bucket/dvc + ssl_verify = False + """ + ) + + with config.edit() as conf: + section = conf["remote"]["remote-name"] + section["ssl_verify"] = "/path/to/custom/cabundle.pem" + + assert (tmp_dir / ".dvc" / "config").read_text() == textwrap.dedent( + """\ + [core] + no_scm = True + ['remote "remote-name"'] + url = s3://bucket/dvc + ssl_verify = /path/to/custom/cabundle.pem + """ + )