Skip to content

Commit aa31706

Browse files
fix: use insecure grpc channel with emulator (#946)
1 parent 1cc1ff7 commit aa31706

File tree

2 files changed

+12
-94
lines changed

2 files changed

+12
-94
lines changed

google/cloud/bigtable/client.py

Lines changed: 7 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import grpc # type: ignore
3333

3434
from google.api_core.gapic_v1 import client_info as client_info_lib
35-
import google.auth # type: ignore
3635
from google.auth.credentials import AnonymousCredentials # type: ignore
3736

3837
from google.cloud import bigtable_v2
@@ -215,58 +214,21 @@ def _get_scopes(self):
215214
return scopes
216215

217216
def _emulator_channel(self, transport, options):
218-
"""Create a channel using self._credentials
217+
"""Create a channel for use with the Bigtable emulator.
219218
220-
Works in a similar way to ``grpc.secure_channel`` but using
221-
``grpc.local_channel_credentials`` rather than
222-
``grpc.ssh_channel_credentials`` to allow easy connection to a
223-
local emulator.
219+
Insecure channels are used for the emulator as secure channels
220+
cannot be used to communicate on some environments.
221+
https://github.com/googleapis/python-firestore/issues/359
224222
225223
Returns:
226224
grpc.Channel or grpc.aio.Channel
227225
"""
228-
# TODO: Implement a special credentials type for emulator and use
229-
# "transport.create_channel" to create gRPC channels once google-auth
230-
# extends it's allowed credentials types.
231226
# Note: this code also exists in the firestore client.
232227
if "GrpcAsyncIOTransport" in str(transport.__name__):
233-
return grpc.aio.secure_channel(
234-
self._emulator_host,
235-
self._local_composite_credentials(),
236-
options=options,
237-
)
228+
channel_fn = grpc.aio.insecure_channel
238229
else:
239-
return grpc.secure_channel(
240-
self._emulator_host,
241-
self._local_composite_credentials(),
242-
options=options,
243-
)
244-
245-
def _local_composite_credentials(self):
246-
"""Create credentials for the local emulator channel.
247-
248-
:return: grpc.ChannelCredentials
249-
"""
250-
credentials = google.auth.credentials.with_scopes_if_required(
251-
self._credentials, None
252-
)
253-
request = google.auth.transport.requests.Request()
254-
255-
# Create the metadata plugin for inserting the authorization header.
256-
metadata_plugin = google.auth.transport.grpc.AuthMetadataPlugin(
257-
credentials, request
258-
)
259-
260-
# Create a set of grpc.CallCredentials using the metadata plugin.
261-
google_auth_credentials = grpc.metadata_call_credentials(metadata_plugin)
262-
263-
# Using the local_credentials to allow connection to emulator
264-
local_credentials = grpc.local_channel_credentials()
265-
266-
# Combine the local credentials and the authorization credentials.
267-
return grpc.composite_channel_credentials(
268-
local_credentials, google_auth_credentials
269-
)
230+
channel_fn = grpc.insecure_channel
231+
return channel_fn(self._emulator_host, options=options)
270232

271233
def _create_gapic_client_channel(self, client_class, grpc_transport):
272234
if self._emulator_host is not None:

tests/unit/v2_client/test_client.py

Lines changed: 5 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ def test_client_constructor_w_emulator_host():
176176

177177
emulator_host = "localhost:8081"
178178
with mock.patch("os.environ", {BIGTABLE_EMULATOR: emulator_host}):
179-
with mock.patch("grpc.secure_channel") as factory:
179+
with mock.patch("grpc.insecure_channel") as factory:
180180
client = _make_client()
181181
# don't test local_composite_credentials
182182
# client._local_composite_credentials = lambda: credentials
@@ -188,7 +188,6 @@ def test_client_constructor_w_emulator_host():
188188
assert client.project == _DEFAULT_BIGTABLE_EMULATOR_CLIENT
189189
factory.assert_called_once_with(
190190
emulator_host,
191-
mock.ANY, # test of creds wrapping in '_emulator_host' below
192191
options=_GRPC_CHANNEL_OPTIONS,
193192
)
194193

@@ -199,7 +198,7 @@ def test_client_constructor_w_emulator_host_w_project():
199198

200199
emulator_host = "localhost:8081"
201200
with mock.patch("os.environ", {BIGTABLE_EMULATOR: emulator_host}):
202-
with mock.patch("grpc.secure_channel") as factory:
201+
with mock.patch("grpc.insecure_channel") as factory:
203202
client = _make_client(project=PROJECT)
204203
# channels are formed when needed, so access a client
205204
# create a gapic channel
@@ -209,7 +208,6 @@ def test_client_constructor_w_emulator_host_w_project():
209208
assert client.project == PROJECT
210209
factory.assert_called_once_with(
211210
emulator_host,
212-
mock.ANY, # test of creds wrapping in '_emulator_host' below
213211
options=_GRPC_CHANNEL_OPTIONS,
214212
)
215213

@@ -222,7 +220,7 @@ def test_client_constructor_w_emulator_host_w_credentials():
222220
emulator_host = "localhost:8081"
223221
credentials = _make_credentials()
224222
with mock.patch("os.environ", {BIGTABLE_EMULATOR: emulator_host}):
225-
with mock.patch("grpc.secure_channel") as factory:
223+
with mock.patch("grpc.insecure_channel") as factory:
226224
client = _make_client(credentials=credentials)
227225
# channels are formed when needed, so access a client
228226
# create a gapic channel
@@ -232,7 +230,6 @@ def test_client_constructor_w_emulator_host_w_credentials():
232230
assert client.project == _DEFAULT_BIGTABLE_EMULATOR_CLIENT
233231
factory.assert_called_once_with(
234232
emulator_host,
235-
mock.ANY, # test of creds wrapping in '_emulator_host' below
236233
options=_GRPC_CHANNEL_OPTIONS,
237234
)
238235

@@ -271,15 +268,13 @@ def test_client__emulator_channel_w_sync():
271268
project=PROJECT, credentials=_make_credentials(), read_only=True
272269
)
273270
client._emulator_host = emulator_host
274-
lcc = client._local_composite_credentials = mock.Mock(spec=[])
275271

276-
with mock.patch("grpc.secure_channel") as patched:
272+
with mock.patch("grpc.insecure_channel") as patched:
277273
channel = client._emulator_channel(transport, options)
278274

279275
assert channel is patched.return_value
280276
patched.assert_called_once_with(
281277
emulator_host,
282-
lcc.return_value,
283278
options=options,
284279
)
285280

@@ -293,56 +288,17 @@ def test_client__emulator_channel_w_async():
293288
project=PROJECT, credentials=_make_credentials(), read_only=True
294289
)
295290
client._emulator_host = emulator_host
296-
lcc = client._local_composite_credentials = mock.Mock(spec=[])
297291

298-
with mock.patch("grpc.aio.secure_channel") as patched:
292+
with mock.patch("grpc.aio.insecure_channel") as patched:
299293
channel = client._emulator_channel(transport, options)
300294

301295
assert channel is patched.return_value
302296
patched.assert_called_once_with(
303297
emulator_host,
304-
lcc.return_value,
305298
options=options,
306299
)
307300

308301

309-
def test_client__local_composite_credentials():
310-
client = _make_client(
311-
project=PROJECT, credentials=_make_credentials(), read_only=True
312-
)
313-
314-
wsir_patch = mock.patch("google.auth.credentials.with_scopes_if_required")
315-
request_patch = mock.patch("google.auth.transport.requests.Request")
316-
amp_patch = mock.patch("google.auth.transport.grpc.AuthMetadataPlugin")
317-
grpc_patches = mock.patch.multiple(
318-
"grpc",
319-
metadata_call_credentials=mock.DEFAULT,
320-
local_channel_credentials=mock.DEFAULT,
321-
composite_channel_credentials=mock.DEFAULT,
322-
)
323-
with wsir_patch as wsir_patched:
324-
with request_patch as request_patched:
325-
with amp_patch as amp_patched:
326-
with grpc_patches as grpc_patched:
327-
credentials = client._local_composite_credentials()
328-
329-
grpc_mcc = grpc_patched["metadata_call_credentials"]
330-
grpc_lcc = grpc_patched["local_channel_credentials"]
331-
grpc_ccc = grpc_patched["composite_channel_credentials"]
332-
333-
assert credentials is grpc_ccc.return_value
334-
335-
wsir_patched.assert_called_once_with(client._credentials, None)
336-
request_patched.assert_called_once_with()
337-
amp_patched.assert_called_once_with(
338-
wsir_patched.return_value,
339-
request_patched.return_value,
340-
)
341-
grpc_mcc.assert_called_once_with(amp_patched.return_value)
342-
grpc_lcc.assert_called_once_with()
343-
grpc_ccc.assert_called_once_with(grpc_lcc.return_value, grpc_mcc.return_value)
344-
345-
346302
def _create_gapic_client_channel_helper(endpoint=None, emulator_host=None):
347303
from google.cloud.bigtable.client import _GRPC_CHANNEL_OPTIONS
348304

0 commit comments

Comments
 (0)