sources/curl: add org.osbuild.mtls secrets support
If `org.osbuild.mtls` is passed as a secret name, look for the mtls data in the environment.
This commit is contained in:
parent
c990c07f79
commit
29159189f1
2 changed files with 104 additions and 6 deletions
|
|
@ -2,13 +2,19 @@
|
|||
"""
|
||||
Source for downloading files from URLs.
|
||||
|
||||
The files are indexed by their content hash. Can download files
|
||||
that require secrets. The only secret provider currently supported
|
||||
is `org.osbuild.rhsm` for downloading Red Hat content that requires
|
||||
a subscriptions.
|
||||
The files are indexed by their content hash. It can download files
|
||||
that require secrets. The secret providers currently supported are:
|
||||
|
||||
Internally use curl to download the files; the files are cached in
|
||||
an internal cache. Multiple parallel connections are used to speed
|
||||
- `org.osbuild.rhsm` for downloading Red Hat content that requires
|
||||
a subscriptions.
|
||||
- `org.osbuild.mtls` for downloading content that requires client
|
||||
certificats. The paths to the key and cert should be set in the
|
||||
environment in OSBUILD_SOURCES_CURL_SSL_CLIENT_KEY,
|
||||
OSBUILD_SOURCES_CURL_SSL_CLIENT_CERT, and optionally
|
||||
OSBUILD_SOURCES_CURL_SSL_CA_CERT.
|
||||
|
||||
It uses curl to download the files; the files are cached in an
|
||||
internal cache. Multiple parallel connections are used to speed
|
||||
up the download.
|
||||
"""
|
||||
|
||||
|
|
@ -107,6 +113,16 @@ class CurlSource(sources.SourceService):
|
|||
if self.subscriptions is None:
|
||||
self.subscriptions = Subscriptions.from_host_system()
|
||||
url["secrets"] = self.subscriptions.get_secrets(url.get("url"))
|
||||
elif url.get("secrets", {}).get("name") == "org.osbuild.mtls":
|
||||
key = os.getenv("OSBUILD_SOURCES_CURL_SSL_CLIENT_KEY")
|
||||
cert = os.getenv("OSBUILD_SOURCES_CURL_SSL_CLIENT_CERT")
|
||||
if not (key and cert):
|
||||
raise RuntimeError(f"mtls secrets required but key ({key}) or cert ({cert}) not defined")
|
||||
url["secrets"] = {
|
||||
'ssl_ca_cert': os.getenv("OSBUILD_SOURCES_CURL_SSL_CA_CERT"),
|
||||
'ssl_client_cert': cert,
|
||||
'ssl_client_key': key,
|
||||
}
|
||||
|
||||
return checksum, url
|
||||
|
||||
|
|
|
|||
82
sources/test/test_curl_source.py
Normal file
82
sources/test/test_curl_source.py
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import contextlib
|
||||
import os
|
||||
import pathlib
|
||||
import socket
|
||||
import tempfile
|
||||
|
||||
import pytest
|
||||
|
||||
SOURCES_NAME = "org.osbuild.curl"
|
||||
|
||||
|
||||
def test_curl_source_not_exists(sources_module):
|
||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
curl_source = sources_module.CurlSource.from_args(["--service-fd", str(sock.fileno())])
|
||||
tmpdir = tempfile.TemporaryDirectory()
|
||||
curl_source.cache = tmpdir.name
|
||||
desc = {
|
||||
"url": "http://localhost:80/a",
|
||||
}
|
||||
checksum = "sha256:1234567890123456789012345678901234567890909b14ffb032aa20fa23d9ad6"
|
||||
assert not curl_source.exists(checksum, desc)
|
||||
|
||||
|
||||
def test_curl_source_exists(sources_module):
|
||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
curl_source = sources_module.CurlSource.from_args(["--service-fd", str(sock.fileno())])
|
||||
tmpdir = tempfile.TemporaryDirectory()
|
||||
curl_source.cache = tmpdir.name
|
||||
desc = {
|
||||
"url": "http://localhost:80/a",
|
||||
}
|
||||
checksum = "sha256:1234567890123456789012345678901234567890909b14ffb032aa20fa23d9ad6"
|
||||
pathlib.Path(os.path.join(tmpdir.name, checksum)).touch()
|
||||
assert curl_source.exists(checksum, desc)
|
||||
|
||||
|
||||
def test_curl_source_transform(sources_module):
|
||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
curl_source = sources_module.CurlSource.from_args(["--service-fd", str(sock.fileno())])
|
||||
tmpdir = tempfile.TemporaryDirectory()
|
||||
curl_source.cache = tmpdir.name
|
||||
desc = {
|
||||
"url": "http://localhost:80/a",
|
||||
"secrets": {
|
||||
"name": "org.osbuild.mtls",
|
||||
},
|
||||
}
|
||||
|
||||
with contextlib.ExitStack() as cm:
|
||||
os.environ["OSBUILD_SOURCES_CURL_SSL_CLIENT_KEY"] = "key"
|
||||
os.environ["OSBUILD_SOURCES_CURL_SSL_CLIENT_CERT"] = "cert"
|
||||
|
||||
def cb():
|
||||
del os.environ["OSBUILD_SOURCES_CURL_SSL_CLIENT_KEY"]
|
||||
del os.environ["OSBUILD_SOURCES_CURL_SSL_CLIENT_CERT"]
|
||||
cm.callback(cb)
|
||||
checksum = "sha256:1234567890123456789012345678901234567890909b14ffb032aa20fa23d9ad6"
|
||||
pathlib.Path(os.path.join(tmpdir.name, checksum)).touch()
|
||||
new_desc = curl_source.transform(checksum, desc)
|
||||
assert new_desc[1]["secrets"]["ssl_client_key"] == "key"
|
||||
assert new_desc[1]["secrets"]["ssl_client_cert"] == "cert"
|
||||
assert new_desc[1]["secrets"]["ssl_ca_cert"] is None
|
||||
|
||||
|
||||
def test_curl_source_transform_fail(sources_module):
|
||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
curl_source = sources_module.CurlSource.from_args(["--service-fd", str(sock.fileno())])
|
||||
tmpdir = tempfile.TemporaryDirectory()
|
||||
curl_source.cache = tmpdir.name
|
||||
desc = {
|
||||
"url": "http://localhost:80/a",
|
||||
"secrets": {
|
||||
"name": "org.osbuild.mtls",
|
||||
},
|
||||
}
|
||||
checksum = "sha256:1234567890123456789012345678901234567890909b14ffb032aa20fa23d9ad6"
|
||||
pathlib.Path(os.path.join(tmpdir.name, checksum)).touch()
|
||||
with pytest.raises(RuntimeError) as exc:
|
||||
curl_source.transform(checksum, desc)
|
||||
assert "mtls secrets required" in str(exc)
|
||||
Loading…
Add table
Add a link
Reference in a new issue