diff --git a/google/cloud/bigtable/client.py b/google/cloud/bigtable/client.py index c82a268c6..0c89ea562 100644 --- a/google/cloud/bigtable/client.py +++ b/google/cloud/bigtable/client.py @@ -32,7 +32,6 @@ import grpc # type: ignore from google.api_core.gapic_v1 import client_info as client_info_lib -import google.auth # type: ignore from google.auth.credentials import AnonymousCredentials # type: ignore from google.cloud import bigtable_v2 @@ -215,58 +214,21 @@ def _get_scopes(self): return scopes def _emulator_channel(self, transport, options): - """Create a channel using self._credentials + """Create a channel for use with the Bigtable emulator. - Works in a similar way to ``grpc.secure_channel`` but using - ``grpc.local_channel_credentials`` rather than - ``grpc.ssh_channel_credentials`` to allow easy connection to a - local emulator. + Insecure channels are used for the emulator as secure channels + cannot be used to communicate on some environments. + https://github.com/googleapis/python-firestore/issues/359 Returns: grpc.Channel or grpc.aio.Channel """ - # TODO: Implement a special credentials type for emulator and use - # "transport.create_channel" to create gRPC channels once google-auth - # extends it's allowed credentials types. # Note: this code also exists in the firestore client. if "GrpcAsyncIOTransport" in str(transport.__name__): - return grpc.aio.secure_channel( - self._emulator_host, - self._local_composite_credentials(), - options=options, - ) + channel_fn = grpc.aio.insecure_channel else: - return grpc.secure_channel( - self._emulator_host, - self._local_composite_credentials(), - options=options, - ) - - def _local_composite_credentials(self): - """Create credentials for the local emulator channel. - - :return: grpc.ChannelCredentials - """ - credentials = google.auth.credentials.with_scopes_if_required( - self._credentials, None - ) - request = google.auth.transport.requests.Request() - - # Create the metadata plugin for inserting the authorization header. - metadata_plugin = google.auth.transport.grpc.AuthMetadataPlugin( - credentials, request - ) - - # Create a set of grpc.CallCredentials using the metadata plugin. - google_auth_credentials = grpc.metadata_call_credentials(metadata_plugin) - - # Using the local_credentials to allow connection to emulator - local_credentials = grpc.local_channel_credentials() - - # Combine the local credentials and the authorization credentials. - return grpc.composite_channel_credentials( - local_credentials, google_auth_credentials - ) + channel_fn = grpc.insecure_channel + return channel_fn(self._emulator_host, options=options) def _create_gapic_client_channel(self, client_class, grpc_transport): if self._emulator_host is not None: diff --git a/tests/unit/v2_client/test_client.py b/tests/unit/v2_client/test_client.py index 5944c58a3..b6eb6ac96 100644 --- a/tests/unit/v2_client/test_client.py +++ b/tests/unit/v2_client/test_client.py @@ -176,7 +176,7 @@ def test_client_constructor_w_emulator_host(): emulator_host = "localhost:8081" with mock.patch("os.environ", {BIGTABLE_EMULATOR: emulator_host}): - with mock.patch("grpc.secure_channel") as factory: + with mock.patch("grpc.insecure_channel") as factory: client = _make_client() # don't test local_composite_credentials # client._local_composite_credentials = lambda: credentials @@ -188,7 +188,6 @@ def test_client_constructor_w_emulator_host(): assert client.project == _DEFAULT_BIGTABLE_EMULATOR_CLIENT factory.assert_called_once_with( emulator_host, - mock.ANY, # test of creds wrapping in '_emulator_host' below options=_GRPC_CHANNEL_OPTIONS, ) @@ -199,7 +198,7 @@ def test_client_constructor_w_emulator_host_w_project(): emulator_host = "localhost:8081" with mock.patch("os.environ", {BIGTABLE_EMULATOR: emulator_host}): - with mock.patch("grpc.secure_channel") as factory: + with mock.patch("grpc.insecure_channel") as factory: client = _make_client(project=PROJECT) # channels are formed when needed, so access a client # create a gapic channel @@ -209,7 +208,6 @@ def test_client_constructor_w_emulator_host_w_project(): assert client.project == PROJECT factory.assert_called_once_with( emulator_host, - mock.ANY, # test of creds wrapping in '_emulator_host' below options=_GRPC_CHANNEL_OPTIONS, ) @@ -222,7 +220,7 @@ def test_client_constructor_w_emulator_host_w_credentials(): emulator_host = "localhost:8081" credentials = _make_credentials() with mock.patch("os.environ", {BIGTABLE_EMULATOR: emulator_host}): - with mock.patch("grpc.secure_channel") as factory: + with mock.patch("grpc.insecure_channel") as factory: client = _make_client(credentials=credentials) # channels are formed when needed, so access a client # create a gapic channel @@ -232,7 +230,6 @@ def test_client_constructor_w_emulator_host_w_credentials(): assert client.project == _DEFAULT_BIGTABLE_EMULATOR_CLIENT factory.assert_called_once_with( emulator_host, - mock.ANY, # test of creds wrapping in '_emulator_host' below options=_GRPC_CHANNEL_OPTIONS, ) @@ -271,15 +268,13 @@ def test_client__emulator_channel_w_sync(): project=PROJECT, credentials=_make_credentials(), read_only=True ) client._emulator_host = emulator_host - lcc = client._local_composite_credentials = mock.Mock(spec=[]) - with mock.patch("grpc.secure_channel") as patched: + with mock.patch("grpc.insecure_channel") as patched: channel = client._emulator_channel(transport, options) assert channel is patched.return_value patched.assert_called_once_with( emulator_host, - lcc.return_value, options=options, ) @@ -293,56 +288,17 @@ def test_client__emulator_channel_w_async(): project=PROJECT, credentials=_make_credentials(), read_only=True ) client._emulator_host = emulator_host - lcc = client._local_composite_credentials = mock.Mock(spec=[]) - with mock.patch("grpc.aio.secure_channel") as patched: + with mock.patch("grpc.aio.insecure_channel") as patched: channel = client._emulator_channel(transport, options) assert channel is patched.return_value patched.assert_called_once_with( emulator_host, - lcc.return_value, options=options, ) -def test_client__local_composite_credentials(): - client = _make_client( - project=PROJECT, credentials=_make_credentials(), read_only=True - ) - - wsir_patch = mock.patch("google.auth.credentials.with_scopes_if_required") - request_patch = mock.patch("google.auth.transport.requests.Request") - amp_patch = mock.patch("google.auth.transport.grpc.AuthMetadataPlugin") - grpc_patches = mock.patch.multiple( - "grpc", - metadata_call_credentials=mock.DEFAULT, - local_channel_credentials=mock.DEFAULT, - composite_channel_credentials=mock.DEFAULT, - ) - with wsir_patch as wsir_patched: - with request_patch as request_patched: - with amp_patch as amp_patched: - with grpc_patches as grpc_patched: - credentials = client._local_composite_credentials() - - grpc_mcc = grpc_patched["metadata_call_credentials"] - grpc_lcc = grpc_patched["local_channel_credentials"] - grpc_ccc = grpc_patched["composite_channel_credentials"] - - assert credentials is grpc_ccc.return_value - - wsir_patched.assert_called_once_with(client._credentials, None) - request_patched.assert_called_once_with() - amp_patched.assert_called_once_with( - wsir_patched.return_value, - request_patched.return_value, - ) - grpc_mcc.assert_called_once_with(amp_patched.return_value) - grpc_lcc.assert_called_once_with() - grpc_ccc.assert_called_once_with(grpc_lcc.return_value, grpc_mcc.return_value) - - def _create_gapic_client_channel_helper(endpoint=None, emulator_host=None): from google.cloud.bigtable.client import _GRPC_CHANNEL_OPTIONS