This is an automated email from the ASF dual-hosted git repository. juergbi pushed a commit to branch juerg/token-auth in repository https://gitbox.apache.org/repos/asf/buildstream.git
commit 12a9d4853c9644b419fc787a16c86623b33a67a9 Author: Jürg Billeter <[email protected]> AuthorDate: Fri Jun 14 08:57:20 2024 +0200 _remotespec.py: Add `access-token` config This adds support for optional HTTP bearer authentication via buildbox-casd. This requires buildbox-casd 1.2.8 or later. --- doc/source/using_config.rst | 6 ++++++ src/buildstream/_cas/casdprocessmanager.py | 2 ++ src/buildstream/_remotespec.py | 24 ++++++++++++++++++------ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/doc/source/using_config.rst b/doc/source/using_config.rst index 926b56438..cf42119be 100644 --- a/doc/source/using_config.rst +++ b/doc/source/using_config.rst @@ -150,6 +150,7 @@ toplevel of your configuration file, like so: server-cert: server.crt client-cert: client.crt client-key: client.key + access-token: access.token Attributes @@ -710,6 +711,7 @@ The ``auth`` configuration block looks like this: server-cert: server.crt client-cert: client.crt client-key: client.key + access-token: access.token Attributes @@ -734,6 +736,10 @@ Attributes The client key is used to encrypt traffic when uploading traffic to the server. +* ``access-token`` + + The path to a token for optional HTTP bearer authentication. + Normally, only the ``server-cert`` is required to securely *download* data from remote cache services, while both the ``client-key`` and ``client-cert`` is required to securely *upload* data to the server. diff --git a/src/buildstream/_cas/casdprocessmanager.py b/src/buildstream/_cas/casdprocessmanager.py index 452a98a60..f65ad4bcc 100644 --- a/src/buildstream/_cas/casdprocessmanager.py +++ b/src/buildstream/_cas/casdprocessmanager.py @@ -93,6 +93,8 @@ class CASDProcessManager: if remote_cache_spec.client_key_file: casd_args.append("--cas-client-key={}".format(remote_cache_spec.client_key_file)) casd_args.append("--cas-client-cert={}".format(remote_cache_spec.client_cert_file)) + if remote_cache_spec.access_token_file: + casd_args.append("--cas-access-token={}".format(remote_cache_spec.access_token_file)) if remote_cache_spec.keepalive_time is not None: casd_args.append("--cas-keepalive-time={}".format(remote_cache_spec.keepalive_time)) diff --git a/src/buildstream/_remotespec.py b/src/buildstream/_remotespec.py index 0fa3cdd12..0845a35cd 100644 --- a/src/buildstream/_remotespec.py +++ b/src/buildstream/_remotespec.py @@ -71,6 +71,7 @@ class RemoteSpec: server_cert: str = None, client_key: str = None, client_cert: str = None, + access_token: str = None, instance_name: Optional[str] = None, connection_config: Optional[MappingNode] = None, spec_node: Optional[MappingNode] = None, @@ -96,6 +97,7 @@ class RemoteSpec: self.server_cert_file: Optional[str] = server_cert self.client_key_file: Optional[str] = client_key self.client_cert_file: Optional[str] = client_cert + self.access_token_file: Optional[str] = access_token # # Private members @@ -133,6 +135,7 @@ class RemoteSpec: self.server_cert_file, self.client_key_file, self.client_cert_file, + self.access_token_file, self.keepalive_time, ) ) @@ -232,6 +235,8 @@ class RemoteSpec: remote.client_key = self.client_key if self.client_cert: remote.client_cert = self.client_cert + if self.access_token_file: + remote.access_token_path = self.access_token_file if self.keepalive_time is not None: remote.keepalive_time.FromSeconds(self.keepalive_time) @@ -257,6 +262,7 @@ class RemoteSpec: server_cert: Optional[str] = None client_key: Optional[str] = None client_cert: Optional[str] = None + access_token: Optional[str] = None push: bool = False remote_type: str = RemoteType.ENDPOINT @@ -281,7 +287,7 @@ class RemoteSpec: auth_node = spec_node.get_mapping("auth", None) if auth_node: - server_cert, client_key, client_cert = cls._parse_auth(auth_node, basedir) + server_cert, client_key, client_cert, access_token = cls._parse_auth(auth_node, basedir) connection_config = spec_node.get_mapping("connection-config", None) @@ -292,6 +298,7 @@ class RemoteSpec: server_cert=server_cert, client_key=client_key, client_cert=client_cert, + access_token=access_token, instance_name=instance_name, connection_config=connection_config, spec_node=spec_node, @@ -323,6 +330,7 @@ class RemoteSpec: server_cert: Optional[str] = None client_key: Optional[str] = None client_cert: Optional[str] = None + access_token: Optional[str] = None if purpose == RemoteSpecPurpose.PULL: push = False @@ -371,6 +379,8 @@ class RemoteSpec: client_key = cls._resolve_path(val, os.getcwd()) elif key == "client-cert": client_cert = cls._resolve_path(val, os.getcwd()) + elif key == "access-token": + access_token = cls._resolve_path(val, os.getcwd()) else: raise RemoteError("Unexpected key '{}' encountered".format(key)) else: @@ -387,6 +397,7 @@ class RemoteSpec: server_cert=server_cert, client_key=client_key, client_cert=client_cert, + access_token=access_token, instance_name=instance_name, ) @@ -417,15 +428,15 @@ class RemoteSpec: # basedir: The base directory which cert files are relative to, or None # # Returns: - # A 3 tuple containing the filenames for the server-cert, - # the client-key and the client-cert + # A 4 tuple containing the filenames for the server-cert, + # the client-key, the client-cert and the access-token # @classmethod def _parse_auth( cls, auth_node: MappingNode, basedir: Optional[str] = None - ) -> Tuple[Optional[str], Optional[str], Optional[str]]: + ) -> Tuple[Optional[str], Optional[str], Optional[str], Optional[str]]: - auth_keys = ["server-cert", "client-key", "client-cert"] + auth_keys = ["server-cert", "client-key", "client-cert", "access-token"] auth_values = {} auth_node.validate_keys(auth_keys) @@ -438,6 +449,7 @@ class RemoteSpec: server_cert = auth_values["server-cert"] client_key = auth_values["client-key"] client_cert = auth_values["client-cert"] + access_token = auth_values["access-token"] if client_key and not client_cert: provenance = auth_node.get_node("client-key").get_provenance() @@ -451,7 +463,7 @@ class RemoteSpec: "{}: 'client-cert' was specified without 'client-key'".format(provenance), LoadErrorReason.INVALID_DATA ) - return server_cert, client_key, client_cert + return server_cert, client_key, client_cert, access_token # _load_credential_files(): #
