From e4eaec0ff255114138d3715280f86d34d861a6fa Mon Sep 17 00:00:00 2001 From: arithmetic1728 <58957152+arithmetic1728@users.noreply.github.com> Date: Wed, 27 May 2020 16:07:49 -0700 Subject: [PATCH] feat: add client_encryped_cert_source to ClientOptions (#31) --- google/api_core/client_options.py | 23 ++++++++++++++++++++-- tests/unit/test_client_options.py | 32 +++++++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/google/api_core/client_options.py b/google/api_core/client_options.py index 7cb49c6c..b6d9384d 100644 --- a/google/api_core/client_options.py +++ b/google/api_core/client_options.py @@ -56,12 +56,31 @@ class ClientOptions(object): api_endpoint (str): The desired API endpoint, e.g., compute.googleapis.com client_cert_source (Callable[[], (bytes, bytes)]): An optional callback which returns client certificate bytes and private key bytes both in - PEM format. + PEM format. ``client_cert_source`` and ``client_encrypted_cert_source`` + are mutually exclusive. + client_encrypted_cert_source (Callable[[], (str, str, bytes)]): An optional + callback which returns client certificate file path, encrypted private + key file path, and the passphrase bytes.``client_cert_source`` and + ``client_encrypted_cert_source`` are mutually exclusive. + + Raises: + ValueError: If both ``client_cert_source`` and ``client_encrypted_cert_source`` + are provided. """ - def __init__(self, api_endpoint=None, client_cert_source=None): + def __init__( + self, + api_endpoint=None, + client_cert_source=None, + client_encrypted_cert_source=None, + ): + if client_cert_source and client_encrypted_cert_source: + raise ValueError( + "client_cert_source and client_encrypted_cert_source are mutually exclusive" + ) self.api_endpoint = api_endpoint self.client_cert_source = client_cert_source + self.client_encrypted_cert_source = client_encrypted_cert_source def __repr__(self): return "ClientOptions: " + repr(self.__dict__) diff --git a/tests/unit/test_client_options.py b/tests/unit/test_client_options.py index 7f175449..67c4f6b4 100644 --- a/tests/unit/test_client_options.py +++ b/tests/unit/test_client_options.py @@ -21,6 +21,10 @@ def get_client_cert(): return b"cert", b"key" +def get_client_encrypted_cert(): + return "cert_path", "key_path", b"passphrase" + + def test_constructor(): options = client_options.ClientOptions( @@ -31,6 +35,30 @@ def test_constructor(): assert options.client_cert_source() == (b"cert", b"key") +def test_constructor_with_encrypted_cert_source(): + + options = client_options.ClientOptions( + api_endpoint="foo.googleapis.com", + client_encrypted_cert_source=get_client_encrypted_cert, + ) + + assert options.api_endpoint == "foo.googleapis.com" + assert options.client_encrypted_cert_source() == ( + "cert_path", + "key_path", + b"passphrase", + ) + + +def test_constructor_with_both_cert_sources(): + with pytest.raises(ValueError): + client_options.ClientOptions( + api_endpoint="foo.googleapis.com", + client_cert_source=get_client_cert, + client_encrypted_cert_source=get_client_encrypted_cert, + ) + + def test_from_dict(): options = client_options.from_dict( {"api_endpoint": "foo.googleapis.com", "client_cert_source": get_client_cert} @@ -57,6 +85,6 @@ def test_repr(): assert ( repr(options) - == "ClientOptions: {'api_endpoint': 'foo.googleapis.com', 'client_cert_source': None}" - or "ClientOptions: {'client_cert_source': None, 'api_endpoint': 'foo.googleapis.com'}" + == "ClientOptions: {'api_endpoint': 'foo.googleapis.com', 'client_cert_source': None, 'client_encrypted_cert_source': None}" + or "ClientOptions: {'client_encrypted_cert_source': None, 'client_cert_source': None, 'api_endpoint': 'foo.googleapis.com'}" )