Skip to content

Commit d1e86fa

Browse files
committed
refactor(api-core): consolidate client_cert and config_helpers into client_utils.py
1 parent 0260fb6 commit d1e86fa

6 files changed

Lines changed: 242 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: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@
1313
# limitations under the License.
1414
#
1515

16-
from typing import Optional
16+
import os
17+
from typing import Any, Callable, Optional, Tuple
1718
from urllib.parse import urlparse, urlunparse
1819

1920
from google.auth.exceptions import MutualTLSChannelError # type: ignore
21+
from google.auth.transport import mtls # type: ignore
2022

2123

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

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)