Skip to content

Commit 5462a36

Browse files
committed
refactor(api-core): consolidate client_cert and config_helpers into client_utils.py
1 parent 4c53e7a commit 5462a36

6 files changed

Lines changed: 240 additions & 327 deletions

File tree

packages/google-api-core/google/api_core/gapic_v1/client_cert.py

Lines changed: 0 additions & 82 deletions
This file was deleted.

packages/google-api-core/google/api_core/gapic_v1/client_utils.py

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616

1717
"""Helpers for client setup and configuration."""
1818

19-
from typing import Any, Optional
19+
import os
20+
from typing import Any, Callable, Optional, Tuple
2021

2122
from google.auth.exceptions import MutualTLSChannelError # type: ignore
23+
from google.auth.transport import mtls # type: ignore
2224

2325

2426
def get_default_mtls_endpoint(api_endpoint: Optional[str]) -> Optional[str]:
@@ -124,3 +126,89 @@ def get_universe_domain(
124126
if not universe_domain:
125127
raise ValueError("Universe Domain cannot be an empty string.")
126128
return universe_domain
129+
130+
131+
def use_client_cert_effective() -> bool:
132+
"""Returns whether client certificate should be used for mTLS if the
133+
google-auth version supports should_use_client_cert automatic mTLS
134+
enablement.
135+
136+
Alternatively, read from the GOOGLE_API_USE_CLIENT_CERTIFICATE env var.
137+
138+
Returns:
139+
bool: whether client certificate should be used for mTLS
140+
Raises:
141+
ValueError: (If using a version of google-auth without
142+
should_use_client_cert and GOOGLE_API_USE_CLIENT_CERTIFICATE is
143+
set to an unexpected value.)
144+
"""
145+
# check if google-auth version supports should_use_client_cert for
146+
# automatic mTLS enablement
147+
if hasattr(mtls, "should_use_client_cert"): # pragma: NO COVER
148+
return mtls.should_use_client_cert()
149+
else: # pragma: NO COVER
150+
# if unsupported, fallback to reading from env var
151+
use_client_cert_str = os.getenv(
152+
"GOOGLE_API_USE_CLIENT_CERTIFICATE", "false"
153+
).lower()
154+
if use_client_cert_str not in ("true", "false"):
155+
raise ValueError(
156+
"Environment variable `GOOGLE_API_USE_CLIENT_CERTIFICATE` "
157+
"must be either `true` or `false`"
158+
)
159+
return use_client_cert_str == "true"
160+
161+
162+
def get_client_cert_source(
163+
provided_cert_source: Optional[Callable[[], Tuple[bytes, bytes]]],
164+
use_cert_flag: bool,
165+
) -> Optional[Callable[[], Tuple[bytes, bytes]]]:
166+
"""Return the client cert source to be used by the client.
167+
168+
Args:
169+
provided_cert_source (Callable[[], Tuple[bytes, bytes]]): The client certificate source provided.
170+
use_cert_flag (bool): A flag indicating whether to use the
171+
client certificate.
172+
173+
Returns:
174+
Callable[[], Tuple[bytes, bytes]] or None: The client cert source to be used by the client.
175+
"""
176+
if use_cert_flag:
177+
if provided_cert_source:
178+
return provided_cert_source
179+
elif (
180+
hasattr(mtls, "has_default_client_cert_source")
181+
and mtls.has_default_client_cert_source()
182+
):
183+
return mtls.default_client_cert_source()
184+
else:
185+
raise ValueError(
186+
"Client certificate is required for mTLS, but no client certificate source was provided or found."
187+
)
188+
return None
189+
190+
191+
def read_environment_variables() -> Tuple[bool, str, Optional[str]]:
192+
"""Returns the environment variables used by the client.
193+
194+
Returns:
195+
Tuple[bool, str, Optional[str]]: returns the
196+
GOOGLE_API_USE_CLIENT_CERTIFICATE, GOOGLE_API_USE_MTLS_ENDPOINT,
197+
and GOOGLE_CLOUD_UNIVERSE_DOMAIN environment variables.
198+
199+
Raises:
200+
ValueError: If GOOGLE_API_USE_CLIENT_CERTIFICATE is not
201+
any of ["true", "false"].
202+
google.auth.exceptions.MutualTLSChannelError: If
203+
GOOGLE_API_USE_MTLS_ENDPOINT is not any of
204+
["auto", "never", "always"].
205+
"""
206+
use_client_cert = use_client_cert_effective()
207+
use_mtls_endpoint = os.getenv("GOOGLE_API_USE_MTLS_ENDPOINT", "auto").lower()
208+
universe_domain_env = os.getenv("GOOGLE_CLOUD_UNIVERSE_DOMAIN")
209+
if use_mtls_endpoint not in ("auto", "never", "always"):
210+
raise MutualTLSChannelError(
211+
"Environment variable `GOOGLE_API_USE_MTLS_ENDPOINT` "
212+
"must be `never`, `auto` or `always`"
213+
)
214+
return use_client_cert, use_mtls_endpoint, universe_domain_env

packages/google-api-core/google/api_core/gapic_v1/config_helpers.py

Lines changed: 0 additions & 50 deletions
This file was deleted.

packages/google-api-core/tests/unit/gapic/test_client_cert.py

Lines changed: 0 additions & 131 deletions
This file was deleted.

0 commit comments

Comments
 (0)