1616#
1717
1818from collections import OrderedDict
19+ from distutils import util
1920import os
2021import re
2122from typing import Callable , Dict , Sequence , Tuple , Type , Union
2728from google .api_core import retry as retries # type: ignore
2829from google .auth import credentials # type: ignore
2930from google .auth .transport import mtls # type: ignore
31+ from google .auth .transport .grpc import SslCredentials # type: ignore
3032from google .auth .exceptions import MutualTLSChannelError # type: ignore
3133from google .oauth2 import service_account # type: ignore
3234
@@ -177,16 +179,19 @@ def __init__(
177179 client_options (ClientOptions): Custom options for the client. It
178180 won't take effect if a ``transport`` instance is provided.
179181 (1) The ``api_endpoint`` property can be used to override the
180- default endpoint provided by the client. GOOGLE_API_USE_MTLS
182+ default endpoint provided by the client. GOOGLE_API_USE_MTLS_ENDPOINT
181183 environment variable can also be used to override the endpoint:
182184 "always" (always use the default mTLS endpoint), "never" (always
183- use the default regular endpoint, this is the default value for
184- the environment variable) and "auto" (auto switch to the default
185- mTLS endpoint if client SSL credentials is present). However,
186- the ``api_endpoint`` property takes precedence if provided.
187- (2) The ``client_cert_source`` property is used to provide client
188- SSL credentials for mutual TLS transport. If not provided, the
189- default SSL credentials will be used if present.
185+ use the default regular endpoint) and "auto" (auto switch to the
186+ default mTLS endpoint if client certificate is present, this is
187+ the default value). However, the ``api_endpoint`` property takes
188+ precedence if provided.
189+ (2) If GOOGLE_API_USE_CLIENT_CERTIFICATE environment variable
190+ is "true", then the ``client_cert_source`` property can be used
191+ to provide client certificate for mutual TLS transport. If
192+ not provided, the default SSL client certificate will be used if
193+ present. If GOOGLE_API_USE_CLIENT_CERTIFICATE is "false" or not
194+ set, no client certificate will be used.
190195 client_info (google.api_core.gapic_v1.client_info.ClientInfo):
191196 The client info used to send a user-agent string along with
192197 API requests. If ``None``, then default info will be used.
@@ -202,25 +207,43 @@ def __init__(
202207 if client_options is None :
203208 client_options = ClientOptions .ClientOptions ()
204209
205- if client_options .api_endpoint is None :
206- use_mtls_env = os .getenv ("GOOGLE_API_USE_MTLS" , "never" )
210+ # Create SSL credentials for mutual TLS if needed.
211+ use_client_cert = bool (
212+ util .strtobool (os .getenv ("GOOGLE_API_USE_CLIENT_CERTIFICATE" , "false" ))
213+ )
214+
215+ ssl_credentials = None
216+ is_mtls = False
217+ if use_client_cert :
218+ if client_options .client_cert_source :
219+ import grpc # type: ignore
220+
221+ cert , key = client_options .client_cert_source ()
222+ ssl_credentials = grpc .ssl_channel_credentials (
223+ certificate_chain = cert , private_key = key
224+ )
225+ is_mtls = True
226+ else :
227+ creds = SslCredentials ()
228+ is_mtls = creds .is_mtls
229+ ssl_credentials = creds .ssl_credentials if is_mtls else None
230+
231+ # Figure out which api endpoint to use.
232+ if client_options .api_endpoint is not None :
233+ api_endpoint = client_options .api_endpoint
234+ else :
235+ use_mtls_env = os .getenv ("GOOGLE_API_USE_MTLS_ENDPOINT" , "auto" )
207236 if use_mtls_env == "never" :
208- client_options . api_endpoint = self .DEFAULT_ENDPOINT
237+ api_endpoint = self .DEFAULT_ENDPOINT
209238 elif use_mtls_env == "always" :
210- client_options . api_endpoint = self .DEFAULT_MTLS_ENDPOINT
239+ api_endpoint = self .DEFAULT_MTLS_ENDPOINT
211240 elif use_mtls_env == "auto" :
212- has_client_cert_source = (
213- client_options .client_cert_source is not None
214- or mtls .has_default_client_cert_source ()
215- )
216- client_options .api_endpoint = (
217- self .DEFAULT_MTLS_ENDPOINT
218- if has_client_cert_source
219- else self .DEFAULT_ENDPOINT
241+ api_endpoint = (
242+ self .DEFAULT_MTLS_ENDPOINT if is_mtls else self .DEFAULT_ENDPOINT
220243 )
221244 else :
222245 raise MutualTLSChannelError (
223- "Unsupported GOOGLE_API_USE_MTLS value. Accepted values: never, auto, always"
246+ "Unsupported GOOGLE_API_USE_MTLS_ENDPOINT value. Accepted values: never, auto, always"
224247 )
225248
226249 # Save or instantiate the transport.
@@ -244,10 +267,9 @@ def __init__(
244267 self ._transport = Transport (
245268 credentials = credentials ,
246269 credentials_file = client_options .credentials_file ,
247- host = client_options . api_endpoint ,
270+ host = api_endpoint ,
248271 scopes = client_options .scopes ,
249- api_mtls_endpoint = client_options .api_endpoint ,
250- client_cert_source = client_options .client_cert_source ,
272+ ssl_channel_credentials = ssl_credentials ,
251273 quota_project_id = client_options .quota_project_id ,
252274 client_info = client_info ,
253275 )
0 commit comments