Merge pull request #19971 from lidizheng/local

Expose local credentials on Python layer
reviewable/pr19036/r2^2
Lidi Zheng 5 years ago committed by GitHub
commit e25e7c921d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 61
      src/python/grpcio/grpc/__init__.py
  2. 5
      src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi
  3. 22
      src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
  4. 12
      src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
  5. 4
      src/python/grpcio_tests/commands.py
  6. 1
      src/python/grpcio_tests/tests/tests.json
  7. 1
      src/python/grpcio_tests/tests/unit/BUILD.bazel
  8. 3
      src/python/grpcio_tests/tests/unit/_api_test.py
  9. 70
      src/python/grpcio_tests/tests/unit/_local_credentials_test.py

@ -1747,6 +1747,64 @@ def dynamic_ssl_server_credentials(initial_certificate_configuration,
certificate_configuration_fetcher, require_client_authentication))
@enum.unique
class LocalConnectionType(enum.Enum):
"""Types of local connection for local credential creation.
Attributes:
UDS: Unix domain socket connections
LOCAL_TCP: Local TCP connections.
"""
UDS = _cygrpc.LocalConnectionType.uds
LOCAL_TCP = _cygrpc.LocalConnectionType.local_tcp
def local_channel_credentials(local_connect_type=LocalConnectionType.LOCAL_TCP):
"""Creates a local ChannelCredentials used for local connections.
This is an EXPERIMENTAL API.
Local credentials are used by local TCP endpoints (e.g. localhost:10000)
also UDS connections. It allows them to create secure channel, hence
transmitting call credentials become possible.
It is useful for 1) eliminating insecure_channel usage; 2) enable unit
testing for call credentials without setting up secrets.
Args:
local_connect_type: Local connection type (either
grpc.LocalConnectionType.UDS or grpc.LocalConnectionType.LOCAL_TCP)
Returns:
A ChannelCredentials for use with a local Channel
"""
return ChannelCredentials(
_cygrpc.channel_credentials_local(local_connect_type.value))
def local_server_credentials(local_connect_type=LocalConnectionType.LOCAL_TCP):
"""Creates a local ServerCredentials used for local connections.
This is an EXPERIMENTAL API.
Local credentials are used by local TCP endpoints (e.g. localhost:10000)
also UDS connections. It allows them to create secure channel, hence
transmitting call credentials become possible.
It is useful for 1) eliminating insecure_channel usage; 2) enable unit
testing for call credentials without setting up secrets.
Args:
local_connect_type: Local connection type (either
grpc.LocalConnectionType.UDS or grpc.LocalConnectionType.LOCAL_TCP)
Returns:
A ServerCredentials for use with a local Server
"""
return ServerCredentials(
_cygrpc.server_credentials_local(local_connect_type.value))
def channel_ready_future(channel):
"""Creates a Future that tracks when a Channel is ready.
@ -1916,6 +1974,7 @@ __all__ = (
'ClientCallDetails',
'ServerCertificateConfiguration',
'ServerCredentials',
'LocalConnectionType',
'UnaryUnaryMultiCallable',
'UnaryStreamMultiCallable',
'StreamUnaryMultiCallable',
@ -1942,6 +2001,8 @@ __all__ = (
'access_token_call_credentials',
'composite_call_credentials',
'composite_channel_credentials',
'local_channel_credentials',
'local_server_credentials',
'ssl_server_credentials',
'ssl_server_certificate_configuration',
'dynamic_ssl_server_credentials',

@ -97,3 +97,8 @@ cdef class ServerCredentials:
cdef object cert_config_fetcher
# whether C-core has asked for the initial_cert_config
cdef bint initial_cert_config_fetched
cdef class LocalChannelCredentials(ChannelCredentials):
cdef grpc_local_connect_type _local_connect_type

@ -328,3 +328,25 @@ cdef grpc_ssl_certificate_config_reload_status _server_cert_config_fetcher_wrapp
cert_config.c_ssl_pem_key_cert_pairs_count)
return GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW
class LocalConnectionType:
uds = UDS
local_tcp = LOCAL_TCP
cdef class LocalChannelCredentials(ChannelCredentials):
def __cinit__(self, grpc_local_connect_type local_connect_type):
self._local_connect_type = local_connect_type
cdef grpc_channel_credentials *c(self) except *:
cdef grpc_local_connect_type local_connect_type
local_connect_type = self._local_connect_type
return grpc_local_credentials_create(local_connect_type)
def channel_credentials_local(grpc_local_connect_type local_connect_type):
return LocalChannelCredentials(local_connect_type)
def server_credentials_local(grpc_local_connect_type local_connect_type):
cdef ServerCredentials credentials = ServerCredentials()
credentials.c_credentials = grpc_local_server_credentials_create(local_connect_type)
return credentials

@ -584,6 +584,12 @@ cdef extern from "grpc/grpc_security.h":
void grpc_auth_context_release(grpc_auth_context *context)
grpc_channel_credentials *grpc_local_credentials_create(
grpc_local_connect_type type)
grpc_server_credentials *grpc_local_server_credentials_create(
grpc_local_connect_type type)
cdef extern from "grpc/compression.h":
ctypedef enum grpc_compression_algorithm:
@ -624,3 +630,9 @@ cdef extern from "grpc/impl/codegen/compression_types.h":
const char *_GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY \
"GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY"
cdef extern from "grpc/grpc_security_constants.h":
ctypedef enum grpc_local_connect_type:
UDS
LOCAL_TCP

@ -154,7 +154,9 @@ class TestGevent(setuptools.Command):
'channelz._channelz_servicer_test.ChannelzServicerTest.test_many_subchannels_and_sockets',
'channelz._channelz_servicer_test.ChannelzServicerTest.test_streaming_rpc',
# TODO(https://github.com/grpc/grpc/issues/15411) enable this test
'unit._cython._channel_test.ChannelTest.test_negative_deadline_connectivity'
'unit._cython._channel_test.ChannelTest.test_negative_deadline_connectivity',
# TODO(https://github.com/grpc/grpc/issues/15411) enable this test
'unit._local_credentials_test.LocalCredentialsTest',
)
BANNED_WINDOWS_TESTS = (
# TODO(https://github.com/grpc/grpc/pull/15411) enable this test

@ -53,6 +53,7 @@
"unit._interceptor_test.InterceptorTest",
"unit._invalid_metadata_test.InvalidMetadataTest",
"unit._invocation_defects_test.InvocationDefectsTest",
"unit._local_credentials_test.LocalCredentialsTest",
"unit._logging_test.LoggingTest",
"unit._metadata_code_details_test.MetadataCodeDetailsTest",
"unit._metadata_flags_test.MetadataFlagsTest",

@ -19,6 +19,7 @@ GRPCIO_TESTS_UNIT = [
"_interceptor_test.py",
"_invalid_metadata_test.py",
"_invocation_defects_test.py",
"_local_credentials_test.py",
"_logging_test.py",
"_metadata_code_details_test.py",
"_metadata_test.py",

@ -60,6 +60,9 @@ class AllTest(unittest.TestCase):
'ServiceRpcHandler',
'Server',
'ServerInterceptor',
'LocalConnectionType',
'local_channel_credentials',
'local_server_credentials',
'unary_unary_rpc_method_handler',
'unary_stream_rpc_method_handler',
'stream_unary_rpc_method_handler',

@ -0,0 +1,70 @@
# Copyright 2019 The gRPC Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Test of RPCs made using local credentials."""
import unittest
from concurrent.futures import ThreadPoolExecutor
import grpc
class _GenericHandler(grpc.GenericRpcHandler):
def service(self, handler_call_details):
return grpc.unary_unary_rpc_method_handler(
lambda request, unused_context: request)
class LocalCredentialsTest(unittest.TestCase):
def _create_server(self):
server = grpc.server(ThreadPoolExecutor())
server.add_generic_rpc_handlers((_GenericHandler(),))
return server
def test_local_tcp(self):
server_addr = 'localhost:{}'
channel_creds = grpc.local_channel_credentials(
grpc.LocalConnectionType.LOCAL_TCP)
server_creds = grpc.local_server_credentials(
grpc.LocalConnectionType.LOCAL_TCP)
server = self._create_server()
port = server.add_secure_port(server_addr.format(0), server_creds)
server.start()
with grpc.secure_channel(server_addr.format(port),
channel_creds) as channel:
self.assertEqual(b'abc',
channel.unary_unary('/test/method')(
b'abc', wait_for_ready=True))
server.stop(None)
def test_uds(self):
server_addr = 'unix:/tmp/grpc_fullstack_test'
channel_creds = grpc.local_channel_credentials(
grpc.LocalConnectionType.UDS)
server_creds = grpc.local_server_credentials(
grpc.LocalConnectionType.UDS)
server = self._create_server()
server.add_secure_port(server_addr, server_creds)
server.start()
with grpc.secure_channel(server_addr, channel_creds) as channel:
self.assertEqual(b'abc',
channel.unary_unary('/test/method')(
b'abc', wait_for_ready=True))
server.stop(None)
if __name__ == '__main__':
unittest.main()
Loading…
Cancel
Save