Merge pull request #24127 from yashykt/meshcaconfig

Add parsing logic for GoogleMeshCaConfig
pull/24173/head
Yash Tibrewal 4 years ago committed by GitHub
commit 3ee45eceef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 18
      BUILD
  2. 4
      BUILD.gn
  3. 43
      CMakeLists.txt
  4. 4
      Makefile
  5. 19
      build_autogenerated.yaml
  6. 2
      config.m4
  7. 2
      config.w32
  8. 4
      gRPC-C++.podspec
  9. 6
      gRPC-Core.podspec
  10. 4
      grpc.gemspec
  11. 3
      grpc.gyp
  12. 4
      package.xml
  13. 39
      src/core/ext/filters/client_channel/resolver_result_parsing.cc
  14. 377
      src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc
  15. 102
      src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h
  16. 58
      src/core/lib/json/json_util.cc
  17. 37
      src/core/lib/json/json_util.h
  18. 2
      src/python/grpcio/grpc_core_dependencies.py
  19. 31
      test/core/xds/BUILD
  20. 367
      test/core/xds/google_mesh_ca_certificate_provider_factory_test.cc
  21. 4
      tools/doxygen/Doxyfile.c++.internal
  22. 4
      tools/doxygen/Doxyfile.core.internal
  23. 24
      tools/run_tests/generated/tests.json

18
BUILD

@ -774,6 +774,7 @@ grpc_cc_library(
"src/core/lib/iomgr/wakeup_fd_posix.cc",
"src/core/lib/iomgr/work_serializer.cc",
"src/core/lib/json/json_reader.cc",
"src/core/lib/json/json_util.cc",
"src/core/lib/json/json_writer.cc",
"src/core/lib/slice/b64.cc",
"src/core/lib/slice/percent_encoding.cc",
@ -919,6 +920,7 @@ grpc_cc_library(
"src/core/lib/iomgr/wakeup_fd_posix.h",
"src/core/lib/iomgr/work_serializer.h",
"src/core/lib/json/json.h",
"src/core/lib/json/json_util.h",
"src/core/lib/slice/b64.h",
"src/core/lib/slice/percent_encoding.h",
"src/core/lib/slice/slice_internal.h",
@ -1323,11 +1325,27 @@ grpc_cc_library(
"envoy_ads_upb",
"grpc_base",
"grpc_client_channel",
"grpc_google_mesh_ca_certificate_provider_factory",
"grpc_secure",
"grpc_xds_api_header",
],
)
grpc_cc_library(
name = "grpc_google_mesh_ca_certificate_provider_factory",
srcs = [
"src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc",
],
hdrs = [
"src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h",
],
language = "c++",
deps = [
"grpc_base",
"grpc_secure",
],
)
grpc_cc_library(
name = "grpc_lb_policy_cds",
srcs = [

@ -547,6 +547,8 @@ config("grpc_config") {
"src/core/ext/xds/certificate_provider_registry.cc",
"src/core/ext/xds/certificate_provider_registry.h",
"src/core/ext/xds/certificate_provider_store.h",
"src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc",
"src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h",
"src/core/ext/xds/xds_api.cc",
"src/core/ext/xds/xds_api.h",
"src/core/ext/xds/xds_bootstrap.cc",
@ -790,6 +792,8 @@ config("grpc_config") {
"src/core/lib/iomgr/work_serializer.h",
"src/core/lib/json/json.h",
"src/core/lib/json/json_reader.cc",
"src/core/lib/json/json_util.cc",
"src/core/lib/json/json_util.h",
"src/core/lib/json/json_writer.cc",
"src/core/lib/security/authorization/authorization_engine.cc",
"src/core/lib/security/authorization/authorization_engine.h",

@ -822,6 +822,7 @@ if(gRPC_BUILD_TESTS)
add_dependencies(buildtests_cxx global_config_env_test)
endif()
add_dependencies(buildtests_cxx global_config_test)
add_dependencies(buildtests_cxx google_mesh_ca_certificate_provider_factory_test)
add_dependencies(buildtests_cxx grpc_cli)
add_dependencies(buildtests_cxx grpc_tls_certificate_distributor_test)
add_dependencies(buildtests_cxx grpc_tls_credentials_options_test)
@ -1598,6 +1599,7 @@ add_library(grpc
src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c
src/core/ext/upb-generated/validate/validate.upb.c
src/core/ext/xds/certificate_provider_registry.cc
src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc
src/core/ext/xds/xds_api.cc
src/core/ext/xds/xds_bootstrap.cc
src/core/ext/xds/xds_client.cc
@ -1725,6 +1727,7 @@ add_library(grpc
src/core/lib/iomgr/wakeup_fd_posix.cc
src/core/lib/iomgr/work_serializer.cc
src/core/lib/json/json_reader.cc
src/core/lib/json/json_util.cc
src/core/lib/json/json_writer.cc
src/core/lib/security/authorization/authorization_engine.cc
src/core/lib/security/authorization/evaluate_args.cc
@ -2340,6 +2343,7 @@ add_library(grpc_unsecure
src/core/lib/iomgr/wakeup_fd_posix.cc
src/core/lib/iomgr/work_serializer.cc
src/core/lib/json/json_reader.cc
src/core/lib/json/json_util.cc
src/core/lib/json/json_writer.cc
src/core/lib/slice/b64.cc
src/core/lib/slice/percent_encoding.cc
@ -11096,6 +11100,45 @@ target_link_libraries(global_config_test
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(google_mesh_ca_certificate_provider_factory_test
test/core/xds/google_mesh_ca_certificate_provider_factory_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(google_mesh_ca_certificate_provider_factory_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_RE2_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
third_party/googletest/googletest/include
third_party/googletest/googletest
third_party/googletest/googlemock/include
third_party/googletest/googlemock
${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(google_mesh_ca_certificate_provider_factory_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
gpr
address_sorting
upb
${_gRPC_GFLAGS_LIBRARIES}
)
endif()
if(gRPC_BUILD_TESTS)

@ -2003,6 +2003,7 @@ LIBGRPC_SRC = \
src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c \
src/core/ext/upb-generated/validate/validate.upb.c \
src/core/ext/xds/certificate_provider_registry.cc \
src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc \
src/core/ext/xds/xds_api.cc \
src/core/ext/xds/xds_bootstrap.cc \
src/core/ext/xds/xds_client.cc \
@ -2130,6 +2131,7 @@ LIBGRPC_SRC = \
src/core/lib/iomgr/wakeup_fd_posix.cc \
src/core/lib/iomgr/work_serializer.cc \
src/core/lib/json/json_reader.cc \
src/core/lib/json/json_util.cc \
src/core/lib/json/json_writer.cc \
src/core/lib/security/authorization/authorization_engine.cc \
src/core/lib/security/authorization/evaluate_args.cc \
@ -2612,6 +2614,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/iomgr/wakeup_fd_posix.cc \
src/core/lib/iomgr/work_serializer.cc \
src/core/lib/json/json_reader.cc \
src/core/lib/json/json_util.cc \
src/core/lib/json/json_writer.cc \
src/core/lib/slice/b64.cc \
src/core/lib/slice/percent_encoding.cc \
@ -4567,6 +4570,7 @@ src/core/ext/upb-generated/udpa/annotations/sensitive.upb.c: $(OPENSSL_DEP)
src/core/ext/upb-generated/udpa/annotations/status.upb.c: $(OPENSSL_DEP)
src/core/ext/upb-generated/udpa/annotations/versioning.upb.c: $(OPENSSL_DEP)
src/core/ext/xds/certificate_provider_registry.cc: $(OPENSSL_DEP)
src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_api.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_bootstrap.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_client.cc: $(OPENSSL_DEP)

@ -538,6 +538,7 @@ libs:
- src/core/ext/xds/certificate_provider_factory.h
- src/core/ext/xds/certificate_provider_registry.h
- src/core/ext/xds/certificate_provider_store.h
- src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h
- src/core/ext/xds/xds_api.h
- src/core/ext/xds/xds_bootstrap.h
- src/core/ext/xds/xds_channel_args.h
@ -654,6 +655,7 @@ libs:
- src/core/lib/iomgr/wakeup_fd_posix.h
- src/core/lib/iomgr/work_serializer.h
- src/core/lib/json/json.h
- src/core/lib/json/json_util.h
- src/core/lib/security/authorization/authorization_engine.h
- src/core/lib/security/authorization/evaluate_args.h
- src/core/lib/security/authorization/mock_cel/activation.h
@ -945,6 +947,7 @@ libs:
- src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c
- src/core/ext/upb-generated/validate/validate.upb.c
- src/core/ext/xds/certificate_provider_registry.cc
- src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc
- src/core/ext/xds/xds_api.cc
- src/core/ext/xds/xds_bootstrap.cc
- src/core/ext/xds/xds_client.cc
@ -1072,6 +1075,7 @@ libs:
- src/core/lib/iomgr/wakeup_fd_posix.cc
- src/core/lib/iomgr/work_serializer.cc
- src/core/lib/json/json_reader.cc
- src/core/lib/json/json_util.cc
- src/core/lib/json/json_writer.cc
- src/core/lib/security/authorization/authorization_engine.cc
- src/core/lib/security/authorization/evaluate_args.cc
@ -1541,6 +1545,7 @@ libs:
- src/core/lib/iomgr/wakeup_fd_posix.h
- src/core/lib/iomgr/work_serializer.h
- src/core/lib/json/json.h
- src/core/lib/json/json_util.h
- src/core/lib/slice/b64.h
- src/core/lib/slice/percent_encoding.h
- src/core/lib/slice/slice_internal.h
@ -1813,6 +1818,7 @@ libs:
- src/core/lib/iomgr/wakeup_fd_posix.cc
- src/core/lib/iomgr/work_serializer.cc
- src/core/lib/json/json_reader.cc
- src/core/lib/json/json_util.cc
- src/core/lib/json/json_writer.cc
- src/core/lib/slice/b64.cc
- src/core/lib/slice/percent_encoding.cc
@ -5821,6 +5827,19 @@ targets:
- address_sorting
- upb
uses_polling: false
- name: google_mesh_ca_certificate_provider_factory_test
gtest: true
build: test
language: c++
headers: []
src:
- test/core/xds/google_mesh_ca_certificate_provider_factory_test.cc
deps:
- grpc_test_util
- grpc
- gpr
- address_sorting
- upb
- name: grpc_cli
build: test
run: false

@ -224,6 +224,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c \
src/core/ext/upb-generated/validate/validate.upb.c \
src/core/ext/xds/certificate_provider_registry.cc \
src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc \
src/core/ext/xds/xds_api.cc \
src/core/ext/xds/xds_bootstrap.cc \
src/core/ext/xds/xds_client.cc \
@ -390,6 +391,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/iomgr/wakeup_fd_posix.cc \
src/core/lib/iomgr/work_serializer.cc \
src/core/lib/json/json_reader.cc \
src/core/lib/json/json_util.cc \
src/core/lib/json/json_writer.cc \
src/core/lib/profiling/basic_timers.cc \
src/core/lib/profiling/stap_timers.cc \

@ -191,6 +191,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\upb-generated\\udpa\\data\\orca\\v1\\orca_load_report.upb.c " +
"src\\core\\ext\\upb-generated\\validate\\validate.upb.c " +
"src\\core\\ext\\xds\\certificate_provider_registry.cc " +
"src\\core\\ext\\xds\\google_mesh_ca_certificate_provider_factory.cc " +
"src\\core\\ext\\xds\\xds_api.cc " +
"src\\core\\ext\\xds\\xds_bootstrap.cc " +
"src\\core\\ext\\xds\\xds_client.cc " +
@ -357,6 +358,7 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\iomgr\\wakeup_fd_posix.cc " +
"src\\core\\lib\\iomgr\\work_serializer.cc " +
"src\\core\\lib\\json\\json_reader.cc " +
"src\\core\\lib\\json\\json_util.cc " +
"src\\core\\lib\\json\\json_writer.cc " +
"src\\core\\lib\\profiling\\basic_timers.cc " +
"src\\core\\lib\\profiling\\stap_timers.cc " +

@ -360,6 +360,7 @@ Pod::Spec.new do |s|
'src/core/ext/xds/certificate_provider_factory.h',
'src/core/ext/xds/certificate_provider_registry.h',
'src/core/ext/xds/certificate_provider_store.h',
'src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h',
'src/core/ext/xds/xds_api.h',
'src/core/ext/xds/xds_bootstrap.h',
'src/core/ext/xds/xds_channel_args.h',
@ -503,6 +504,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/wakeup_fd_posix.h',
'src/core/lib/iomgr/work_serializer.h',
'src/core/lib/json/json.h',
'src/core/lib/json/json_util.h',
'src/core/lib/profiling/timers.h',
'src/core/lib/security/authorization/authorization_engine.h',
'src/core/lib/security/authorization/evaluate_args.h',
@ -864,6 +866,7 @@ Pod::Spec.new do |s|
'src/core/ext/xds/certificate_provider_factory.h',
'src/core/ext/xds/certificate_provider_registry.h',
'src/core/ext/xds/certificate_provider_store.h',
'src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h',
'src/core/ext/xds/xds_api.h',
'src/core/ext/xds/xds_bootstrap.h',
'src/core/ext/xds/xds_channel_args.h',
@ -1007,6 +1010,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/wakeup_fd_posix.h',
'src/core/lib/iomgr/work_serializer.h',
'src/core/lib/json/json.h',
'src/core/lib/json/json_util.h',
'src/core/lib/profiling/timers.h',
'src/core/lib/security/authorization/authorization_engine.h',
'src/core/lib/security/authorization/evaluate_args.h',

@ -533,6 +533,8 @@ Pod::Spec.new do |s|
'src/core/ext/xds/certificate_provider_registry.cc',
'src/core/ext/xds/certificate_provider_registry.h',
'src/core/ext/xds/certificate_provider_store.h',
'src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc',
'src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h',
'src/core/ext/xds/xds_api.cc',
'src/core/ext/xds/xds_api.h',
'src/core/ext/xds/xds_bootstrap.cc',
@ -842,6 +844,8 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/work_serializer.h',
'src/core/lib/json/json.h',
'src/core/lib/json/json_reader.cc',
'src/core/lib/json/json_util.cc',
'src/core/lib/json/json_util.h',
'src/core/lib/json/json_writer.cc',
'src/core/lib/profiling/basic_timers.cc',
'src/core/lib/profiling/stap_timers.cc',
@ -1289,6 +1293,7 @@ Pod::Spec.new do |s|
'src/core/ext/xds/certificate_provider_factory.h',
'src/core/ext/xds/certificate_provider_registry.h',
'src/core/ext/xds/certificate_provider_store.h',
'src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h',
'src/core/ext/xds/xds_api.h',
'src/core/ext/xds/xds_bootstrap.h',
'src/core/ext/xds/xds_channel_args.h',
@ -1432,6 +1437,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/wakeup_fd_posix.h',
'src/core/lib/iomgr/work_serializer.h',
'src/core/lib/json/json.h',
'src/core/lib/json/json_util.h',
'src/core/lib/profiling/timers.h',
'src/core/lib/security/authorization/authorization_engine.h',
'src/core/lib/security/authorization/evaluate_args.h',

@ -451,6 +451,8 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/xds/certificate_provider_registry.cc )
s.files += %w( src/core/ext/xds/certificate_provider_registry.h )
s.files += %w( src/core/ext/xds/certificate_provider_store.h )
s.files += %w( src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc )
s.files += %w( src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h )
s.files += %w( src/core/ext/xds/xds_api.cc )
s.files += %w( src/core/ext/xds/xds_api.h )
s.files += %w( src/core/ext/xds/xds_bootstrap.cc )
@ -760,6 +762,8 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/work_serializer.h )
s.files += %w( src/core/lib/json/json.h )
s.files += %w( src/core/lib/json/json_reader.cc )
s.files += %w( src/core/lib/json/json_util.cc )
s.files += %w( src/core/lib/json/json_util.h )
s.files += %w( src/core/lib/json/json_writer.cc )
s.files += %w( src/core/lib/profiling/basic_timers.cc )
s.files += %w( src/core/lib/profiling/stap_timers.cc )

@ -629,6 +629,7 @@
'src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c',
'src/core/ext/upb-generated/validate/validate.upb.c',
'src/core/ext/xds/certificate_provider_registry.cc',
'src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc',
'src/core/ext/xds/xds_api.cc',
'src/core/ext/xds/xds_bootstrap.cc',
'src/core/ext/xds/xds_client.cc',
@ -756,6 +757,7 @@
'src/core/lib/iomgr/wakeup_fd_posix.cc',
'src/core/lib/iomgr/work_serializer.cc',
'src/core/lib/json/json_reader.cc',
'src/core/lib/json/json_util.cc',
'src/core/lib/json/json_writer.cc',
'src/core/lib/security/authorization/authorization_engine.cc',
'src/core/lib/security/authorization/evaluate_args.cc',
@ -1201,6 +1203,7 @@
'src/core/lib/iomgr/wakeup_fd_posix.cc',
'src/core/lib/iomgr/work_serializer.cc',
'src/core/lib/json/json_reader.cc',
'src/core/lib/json/json_util.cc',
'src/core/lib/json/json_writer.cc',
'src/core/lib/slice/b64.cc',
'src/core/lib/slice/percent_encoding.cc',

@ -431,6 +431,8 @@
<file baseinstalldir="/" name="src/core/ext/xds/certificate_provider_registry.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/certificate_provider_registry.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/certificate_provider_store.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_api.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_api.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_bootstrap.cc" role="src" />
@ -740,6 +742,8 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/work_serializer.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/json/json.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/json/json_reader.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/json/json_util.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/json/json_util.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/json/json_writer.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/profiling/basic_timers.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/profiling/stap_timers.cc" role="src" />

@ -38,6 +38,7 @@
#include "src/core/lib/channel/status_util.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/json/json_util.h"
#include "src/core/lib/uri/uri_parser.h"
// As per the retry design, we do not allow more than 5 retry attempts.
@ -62,38 +63,6 @@ void ClientChannelServiceConfigParser::Register() {
namespace {
// Parses a JSON field of the form generated for a google.proto.Duration
// proto message, as per:
// https://developers.google.com/protocol-buffers/docs/proto3#json
bool ParseDuration(const Json& field, grpc_millis* duration) {
if (field.type() != Json::Type::STRING) return false;
size_t len = field.string_value().size();
if (field.string_value()[len - 1] != 's') return false;
grpc_core::UniquePtr<char> buf(gpr_strdup(field.string_value().c_str()));
*(buf.get() + len - 1) = '\0'; // Remove trailing 's'.
char* decimal_point = strchr(buf.get(), '.');
int nanos = 0;
if (decimal_point != nullptr) {
*decimal_point = '\0';
nanos = gpr_parse_nonnegative_int(decimal_point + 1);
if (nanos == -1) {
return false;
}
int num_digits = static_cast<int>(strlen(decimal_point + 1));
if (num_digits > 9) { // We don't accept greater precision than nanos.
return false;
}
for (int i = 0; i < (9 - num_digits); ++i) {
nanos *= 10;
}
}
int seconds =
decimal_point == buf.get() ? 0 : gpr_parse_nonnegative_int(buf.get());
if (seconds == -1) return false;
*duration = seconds * GPR_MS_PER_SEC + nanos / GPR_NS_PER_MS;
return true;
}
std::unique_ptr<ClientChannelMethodParsedConfig::RetryPolicy> ParseRetryPolicy(
const Json& json, grpc_error** error) {
GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
@ -128,7 +97,7 @@ std::unique_ptr<ClientChannelMethodParsedConfig::RetryPolicy> ParseRetryPolicy(
// Parse initialBackoff.
it = json.object_value().find("initialBackoff");
if (it != json.object_value().end()) {
if (!ParseDuration(it->second, &retry_policy->initial_backoff)) {
if (!ParseDurationFromJson(it->second, &retry_policy->initial_backoff)) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:initialBackoff error:Failed to parse"));
} else if (retry_policy->initial_backoff == 0) {
@ -139,7 +108,7 @@ std::unique_ptr<ClientChannelMethodParsedConfig::RetryPolicy> ParseRetryPolicy(
// Parse maxBackoff.
it = json.object_value().find("maxBackoff");
if (it != json.object_value().end()) {
if (!ParseDuration(it->second, &retry_policy->max_backoff)) {
if (!ParseDurationFromJson(it->second, &retry_policy->max_backoff)) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:maxBackoff error:failed to parse"));
} else if (retry_policy->max_backoff == 0) {
@ -416,7 +385,7 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const Json& json,
// Parse timeout.
it = json.object_value().find("timeout");
if (it != json.object_value().end()) {
if (!ParseDuration(it->second, &timeout)) {
if (!ParseDurationFromJson(it->second, &timeout)) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:timeout error:Failed parsing"));
};

@ -0,0 +1,377 @@
//
//
// Copyright 2020 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.
//
//
#include <grpc/support/port_platform.h>
#include "src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h"
#include <sstream>
#include <type_traits>
#include "absl/strings/str_cat.h"
#include <grpc/support/string_util.h>
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/json/json_util.h"
namespace grpc_core {
namespace {
const char* kMeshCaPlugin = "meshCA";
//
// Helper functions for extracting types from JSON
//
template <typename NumericType, typename ErrorVectorType>
bool ExtractJsonType(const Json& json, const std::string& field_name,
NumericType* output, ErrorVectorType* error_list) {
static_assert(std::is_integral<NumericType>::value, "Integral required");
if (json.type() != Json::Type::NUMBER) {
error_list->push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(
absl::StrCat("field:", field_name, " error:type should be NUMBER")
.c_str()));
return false;
}
std::istringstream ss(json.string_value());
ss >> *output;
// The JSON parsing API should have dealt with parsing errors, but check
// anyway
if (GPR_UNLIKELY(ss.bad())) {
error_list->push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(
absl::StrCat("field:", field_name, " error:failed to parse.").c_str()));
return false;
}
return true;
}
template <typename ErrorVectorType>
bool ExtractJsonType(const Json& json, const std::string& field_name,
bool* output, ErrorVectorType* error_list) {
switch (json.type()) {
case Json::Type::JSON_TRUE:
*output = true;
return true;
case Json::Type::JSON_FALSE:
*output = false;
return true;
default:
error_list->push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(
absl::StrCat("field:", field_name, " error:type should be BOOLEAN")
.c_str()));
return false;
}
}
template <typename ErrorVectorType>
bool ExtractJsonType(const Json& json, const std::string& field_name,
std::string* output, ErrorVectorType* error_list) {
if (json.type() != Json::Type::STRING) {
*output = "";
error_list->push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(
absl::StrCat("field:", field_name, " error:type should be STRING")
.c_str()));
return false;
}
*output = json.string_value();
return true;
}
template <typename ErrorVectorType>
bool ExtractJsonType(const Json& json, const std::string& field_name,
const Json::Array** output, ErrorVectorType* error_list) {
if (json.type() != Json::Type::ARRAY) {
*output = nullptr;
error_list->push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(
absl::StrCat("field:", field_name, " error:type should be ARRAY")
.c_str()));
return false;
}
*output = &json.array_value();
return true;
}
template <typename ErrorVectorType>
bool ExtractJsonType(const Json& json, const std::string& field_name,
const Json::Object** output, ErrorVectorType* error_list) {
if (json.type() != Json::Type::OBJECT) {
*output = nullptr;
error_list->push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(
absl::StrCat("field:", field_name, " error:type should be OBJECT")
.c_str()));
return false;
}
*output = &json.object_value();
return true;
}
template <typename ErrorVectorType>
bool ExtractJsonType(const Json& json, const std::string& field_name,
grpc_millis* output, ErrorVectorType* error_list) {
if (!ParseDurationFromJson(json, output)) {
*output = GRPC_MILLIS_INF_PAST;
error_list->push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(
absl::StrCat("field:", field_name,
" error:type should be STRING of the form given by "
"google.proto.Duration.")
.c_str()));
return false;
}
return true;
}
template <typename T, typename ErrorVectorType>
bool ParseJsonObjectField(const Json::Object& object,
const std::string& field_name, T* output,
ErrorVectorType* error_list, bool optional = false) {
auto it = object.find(field_name);
if (it == object.end()) {
if (!optional) {
error_list->push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(
absl::StrCat("field:", field_name, " error:does not exist.")
.c_str()));
}
return false;
}
auto& child_object_json = it->second;
return ExtractJsonType(child_object_json, field_name, output, error_list);
}
} // namespace
//
// GoogleMeshCaCertificateProviderFactory::Config
//
const char* GoogleMeshCaCertificateProviderFactory::Config::name() const {
return kMeshCaPlugin;
}
std::vector<grpc_error*>
GoogleMeshCaCertificateProviderFactory::Config::ParseJsonObjectStsService(
const Json::Object& sts_service) {
std::vector<grpc_error*> error_list_sts_service;
if (!ParseJsonObjectField(sts_service, "token_exchange_service_uri",
&sts_config_.token_exchange_service_uri,
&error_list_sts_service, true)) {
sts_config_.token_exchange_service_uri =
"securetoken.googleapis.com"; // default
}
ParseJsonObjectField(sts_service, "resource", &sts_config_.resource,
&error_list_sts_service, true);
ParseJsonObjectField(sts_service, "audience", &sts_config_.audience,
&error_list_sts_service, true);
if (!ParseJsonObjectField(sts_service, "scope", &sts_config_.scope,
&error_list_sts_service, true)) {
sts_config_.scope =
"https://www.googleapis.com/auth/cloud-platform"; // default
}
ParseJsonObjectField(sts_service, "requested_token_type",
&sts_config_.requested_token_type,
&error_list_sts_service, true);
ParseJsonObjectField(sts_service, "subject_token_path",
&sts_config_.subject_token_path,
&error_list_sts_service);
ParseJsonObjectField(sts_service, "subject_token_type",
&sts_config_.subject_token_type,
&error_list_sts_service);
ParseJsonObjectField(sts_service, "actor_token_path",
&sts_config_.actor_token_path, &error_list_sts_service,
true);
ParseJsonObjectField(sts_service, "actor_token_type",
&sts_config_.actor_token_type, &error_list_sts_service,
true);
return error_list_sts_service;
}
std::vector<grpc_error*>
GoogleMeshCaCertificateProviderFactory::Config::ParseJsonObjectCallCredentials(
const Json::Object& call_credentials) {
std::vector<grpc_error*> error_list_call_credentials;
const Json::Object* sts_service = nullptr;
if (ParseJsonObjectField(call_credentials, "sts_service", &sts_service,
&error_list_call_credentials)) {
std::vector<grpc_error*> error_list_sts_service =
ParseJsonObjectStsService(*sts_service);
if (!error_list_sts_service.empty()) {
error_list_call_credentials.push_back(GRPC_ERROR_CREATE_FROM_VECTOR(
"field:sts_service", &error_list_sts_service));
}
}
return error_list_call_credentials;
}
std::vector<grpc_error*>
GoogleMeshCaCertificateProviderFactory::Config::ParseJsonObjectGoogleGrpc(
const Json::Object& google_grpc) {
std::vector<grpc_error*> error_list_google_grpc;
if (!ParseJsonObjectField(google_grpc, "target_uri", &endpoint_,
&error_list_google_grpc, true)) {
endpoint_ = "meshca.googleapis.com"; // Default target
}
const Json::Array* call_credentials_array = nullptr;
if (ParseJsonObjectField(google_grpc, "call_credentials",
&call_credentials_array, &error_list_google_grpc)) {
if (call_credentials_array->size() != 1) {
error_list_google_grpc.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:call_credentials error:Need exactly one entry."));
} else {
const Json::Object* call_credentials = nullptr;
if (ExtractJsonType((*call_credentials_array)[0], "call_credentials[0]",
&call_credentials, &error_list_google_grpc)) {
std::vector<grpc_error*> error_list_call_credentials =
ParseJsonObjectCallCredentials(*call_credentials);
if (!error_list_call_credentials.empty()) {
error_list_google_grpc.push_back(GRPC_ERROR_CREATE_FROM_VECTOR(
"field:call_credentials", &error_list_call_credentials));
}
}
}
}
return error_list_google_grpc;
}
std::vector<grpc_error*>
GoogleMeshCaCertificateProviderFactory::Config::ParseJsonObjectGrpcServices(
const Json::Object& grpc_service) {
std::vector<grpc_error*> error_list_grpc_services;
const Json::Object* google_grpc = nullptr;
if (ParseJsonObjectField(grpc_service, "google_grpc", &google_grpc,
&error_list_grpc_services)) {
std::vector<grpc_error*> error_list_google_grpc =
ParseJsonObjectGoogleGrpc(*google_grpc);
if (!error_list_google_grpc.empty()) {
error_list_grpc_services.push_back(GRPC_ERROR_CREATE_FROM_VECTOR(
"field:google_grpc", &error_list_google_grpc));
}
}
if (!ParseJsonObjectField(grpc_service, "timeout", &timeout_,
&error_list_grpc_services, true)) {
timeout_ = 10 * 1000; // 10sec default
}
return error_list_grpc_services;
}
std::vector<grpc_error*>
GoogleMeshCaCertificateProviderFactory::Config::ParseJsonObjectServer(
const Json::Object& server) {
std::vector<grpc_error*> error_list_server;
std::string api_type;
if (ParseJsonObjectField(server, "api_type", &api_type, &error_list_server,
true)) {
if (api_type != "GRPC") {
error_list_server.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:api_type error:Only GRPC is supported"));
}
}
const Json::Array* grpc_services = nullptr;
if (ParseJsonObjectField(server, "grpc_services", &grpc_services,
&error_list_server)) {
if (grpc_services->size() != 1) {
error_list_server.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:grpc_services error:Need exactly one entry"));
} else {
const Json::Object* grpc_service = nullptr;
if (ExtractJsonType((*grpc_services)[0], "grpc_services[0]",
&grpc_service, &error_list_server)) {
std::vector<grpc_error*> error_list_grpc_services =
ParseJsonObjectGrpcServices(*grpc_service);
if (!error_list_grpc_services.empty()) {
error_list_server.push_back(GRPC_ERROR_CREATE_FROM_VECTOR(
"field:grpc_services", &error_list_grpc_services));
}
}
}
}
return error_list_server;
}
std::unique_ptr<GoogleMeshCaCertificateProviderFactory::Config>
GoogleMeshCaCertificateProviderFactory::Config::Parse(const Json& config_json,
grpc_error** error) {
auto config =
absl::make_unique<GoogleMeshCaCertificateProviderFactory::Config>();
if (config_json.type() != Json::Type::OBJECT) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"error:config type should be OBJECT.");
return nullptr;
}
std::vector<grpc_error*> error_list;
const Json::Object* server = nullptr;
if (ParseJsonObjectField(config_json.object_value(), "server", &server,
&error_list)) {
std::vector<grpc_error*> error_list_server =
config->ParseJsonObjectServer(*server);
if (!error_list_server.empty()) {
error_list.push_back(
GRPC_ERROR_CREATE_FROM_VECTOR("field:server", &error_list_server));
}
}
if (!ParseJsonObjectField(config_json.object_value(), "certificate_lifetime",
&config->certificate_lifetime_, &error_list,
true)) {
config->certificate_lifetime_ = 24 * 60 * 60 * 1000; // 24hrs default
}
if (!ParseJsonObjectField(config_json.object_value(), "renewal_grace_period",
&config->renewal_grace_period_, &error_list,
true)) {
config->renewal_grace_period_ = 12 * 60 * 60 * 1000; // 12hrs default
}
std::string key_type;
if (ParseJsonObjectField(config_json.object_value(), "key_type", &key_type,
&error_list, true)) {
if (key_type != "RSA") {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:key_type error:Only RSA is supported."));
}
}
if (!ParseJsonObjectField(config_json.object_value(), "key_size",
&config->key_size_, &error_list, true)) {
config->key_size_ = 2048; // default 2048 bit key size
}
if (!ParseJsonObjectField(config_json.object_value(), "location",
&config->location_, &error_list, true)) {
// GCE/GKE Metadata server needs to be contacted to get the value.
}
if (!error_list.empty()) {
*error = GRPC_ERROR_CREATE_FROM_VECTOR(
"Error parsing google Mesh CA config", &error_list);
return nullptr;
}
return config;
}
//
// GoogleMeshCaCertificateProviderFactory
//
const char* GoogleMeshCaCertificateProviderFactory::name() const {
return kMeshCaPlugin;
}
std::unique_ptr<CertificateProviderFactory::Config>
GoogleMeshCaCertificateProviderFactory::CreateCertificateProviderConfig(
const Json& config_json, grpc_error** error) {
return GoogleMeshCaCertificateProviderFactory::Config::Parse(config_json,
error);
}
} // namespace grpc_core

@ -0,0 +1,102 @@
//
//
// Copyright 2020 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.
//
//
#ifndef GRPC_CORE_EXT_XDS_GOOGLE_MESH_CA_CERTIFICATE_PROVIDER_FACTORY_H
#define GRPC_CORE_EXT_XDS_GOOGLE_MESH_CA_CERTIFICATE_PROVIDER_FACTORY_H
#include <grpc/support/port_platform.h>
#include "src/core/ext/xds/certificate_provider_factory.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/gprpp/ref_counted.h"
namespace grpc_core {
class GoogleMeshCaCertificateProviderFactory
: public CertificateProviderFactory {
public:
class Config : public CertificateProviderFactory::Config {
public:
struct StsConfig {
std::string token_exchange_service_uri;
std::string resource;
std::string audience;
std::string scope;
std::string requested_token_type;
std::string subject_token_path;
std::string subject_token_type;
std::string actor_token_path;
std::string actor_token_type;
};
const char* name() const override;
const std::string& endpoint() const { return endpoint_; }
const StsConfig& sts_config() const { return sts_config_; }
grpc_millis timeout() const { return timeout_; }
grpc_millis certificate_lifetime() const { return certificate_lifetime_; }
grpc_millis renewal_grace_period() const { return renewal_grace_period_; }
uint32_t key_size() const { return key_size_; }
const std::string& location() const { return location_; }
static std::unique_ptr<Config> Parse(const Json& config_json,
grpc_error** error);
private:
// Helpers for parsing the config
std::vector<grpc_error*> ParseJsonObjectStsService(
const Json::Object& sts_service);
std::vector<grpc_error*> ParseJsonObjectCallCredentials(
const Json::Object& call_credentials);
std::vector<grpc_error*> ParseJsonObjectGoogleGrpc(
const Json::Object& google_grpc);
std::vector<grpc_error*> ParseJsonObjectGrpcServices(
const Json::Object& grpc_service);
std::vector<grpc_error*> ParseJsonObjectServer(const Json::Object& server);
std::string endpoint_;
StsConfig sts_config_;
grpc_millis timeout_;
grpc_millis certificate_lifetime_;
grpc_millis renewal_grace_period_;
uint32_t key_size_;
std::string location_;
};
const char* name() const override;
std::unique_ptr<CertificateProviderFactory::Config>
CreateCertificateProviderConfig(const Json& config_json,
grpc_error** error) override;
RefCountedPtr<grpc_tls_certificate_provider> CreateCertificateProvider(
std::unique_ptr<CertificateProviderFactory::Config> config) override {
// TODO(yashykt) : To be implemented
return nullptr;
}
};
} // namespace grpc_core
#endif // GRPC_CORE_EXT_XDS_GOOGLE_MESH_CA_CERTIFICATE_PROVIDER_FACTORY_H

@ -0,0 +1,58 @@
//
//
// Copyright 2020 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.
//
//
#include <grpc/support/port_platform.h>
#include "src/core/lib/json/json_util.h"
#include <grpc/support/string_util.h>
#include "src/core/lib/gpr/string.h"
namespace grpc_core {
bool ParseDurationFromJson(const Json& field, grpc_millis* duration) {
if (field.type() != Json::Type::STRING) return false;
size_t len = field.string_value().size();
if (field.string_value()[len - 1] != 's') return false;
grpc_core::UniquePtr<char> buf(gpr_strdup(field.string_value().c_str()));
*(buf.get() + len - 1) = '\0'; // Remove trailing 's'.
char* decimal_point = strchr(buf.get(), '.');
int nanos = 0;
if (decimal_point != nullptr) {
*decimal_point = '\0';
nanos = gpr_parse_nonnegative_int(decimal_point + 1);
if (nanos == -1) {
return false;
}
int num_digits = static_cast<int>(strlen(decimal_point + 1));
if (num_digits > 9) { // We don't accept greater precision than nanos.
return false;
}
for (int i = 0; i < (9 - num_digits); ++i) {
nanos *= 10;
}
}
int seconds =
decimal_point == buf.get() ? 0 : gpr_parse_nonnegative_int(buf.get());
if (seconds == -1) return false;
*duration = seconds * GPR_MS_PER_SEC + nanos / GPR_NS_PER_MS;
return true;
}
} // namespace grpc_core

@ -0,0 +1,37 @@
//
//
// Copyright 2020 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.
//
//
#ifndef GRPC_CORE_LIB_JSON_JSON_UTIL_H
#define GRPC_CORE_LIB_JSON_JSON_UTIL_H
#include <grpc/support/port_platform.h>
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/json/json.h"
namespace grpc_core {
// Parses a JSON field of the form generated for a google.proto.Duration
// proto message, as per:
// https://developers.google.com/protocol-buffers/docs/proto3#json
// Returns true on success, false otherwise.
bool ParseDurationFromJson(const Json& field, grpc_millis* duration);
} // namespace grpc_core
#endif // GRPC_CORE_LIB_JSON_JSON_UTIL_H

@ -200,6 +200,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c',
'src/core/ext/upb-generated/validate/validate.upb.c',
'src/core/ext/xds/certificate_provider_registry.cc',
'src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc',
'src/core/ext/xds/xds_api.cc',
'src/core/ext/xds/xds_bootstrap.cc',
'src/core/ext/xds/xds_client.cc',
@ -366,6 +367,7 @@ CORE_SOURCE_FILES = [
'src/core/lib/iomgr/wakeup_fd_posix.cc',
'src/core/lib/iomgr/work_serializer.cc',
'src/core/lib/json/json_reader.cc',
'src/core/lib/json/json_util.cc',
'src/core/lib/json/json_writer.cc',
'src/core/lib/profiling/basic_timers.cc',
'src/core/lib/profiling/stap_timers.cc',

@ -0,0 +1,31 @@
# Copyright 2020 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.
load("//bazel:grpc_build_system.bzl", "grpc_cc_test", "grpc_package")
grpc_package(name = "test/core/client_channel")
licenses(["notice"])
grpc_cc_test(
name = "google_mesh_ca_certificate_provider_factory_test",
srcs = ["google_mesh_ca_certificate_provider_factory_test.cc"],
external_deps = ["gtest"],
language = "C++",
deps = [
"//:gpr",
"//:grpc",
"//test/core/util:grpc_test_util",
],
)

@ -0,0 +1,367 @@
//
//
// Copyright 2020 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.
//
//
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <grpc/grpc.h>
#include "src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h"
#include "test/core/util/test_config.h"
namespace grpc_core {
namespace testing {
namespace {
TEST(GoogleMeshCaConfigTest, Basic) {
const char* json_str =
"{"
" \"server\": {"
" \"api_type\": \"GRPC\","
" \"grpc_services\": [{"
" \"google_grpc\": {"
" \"target_uri\": \"newmeshca.googleapis.com\","
" \"channel_credentials\": { \"google_default\": {}},"
" \"call_credentials\": [{"
" \"sts_service\": {"
" \"token_exchange_service_uri\": "
"\"newsecuretoken.googleapis.com\","
" \"resource\": \"newmeshca.googleapis.com\","
" \"audience\": \"newmeshca.googleapis.com\","
" \"scope\": "
"\"https://www.newgoogleapis.com/auth/cloud-platform\","
" \"requested_token_type\": "
"\"urn:ietf:params:oauth:token-type:jwt\","
" \"subject_token_path\": \"/etc/secret/sajwt.token\","
" \"subject_token_type\": "
"\"urn:ietf:params:oauth:token-type:jwt\","
" \"actor_token_path\": \"/etc/secret/sajwt.token\","
" \"actor_token_type\": "
"\"urn:ietf:params:oauth:token-type:jwt\""
" }"
" }]"
" },"
" \"timeout\": \"20s\""
" }]"
" },"
" \"certificate_lifetime\": \"400s\","
" \"renewal_grace_period\": \"100s\","
" \"key_type\": \"RSA\","
" \"key_size\": 1024,"
" \"location\": "
"\"https://container.googleapis.com/v1/project/test-project1/locations/"
"test-zone2/clusters/test-cluster3\""
"}";
grpc_error* error = GRPC_ERROR_NONE;
Json json = Json::Parse(json_str, &error);
ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
auto config =
GoogleMeshCaCertificateProviderFactory::Config::Parse(json, &error);
ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
EXPECT_EQ(config->endpoint(), "newmeshca.googleapis.com");
EXPECT_EQ(config->sts_config().token_exchange_service_uri,
"newsecuretoken.googleapis.com");
EXPECT_EQ(config->sts_config().resource, "newmeshca.googleapis.com");
EXPECT_EQ(config->sts_config().audience, "newmeshca.googleapis.com");
EXPECT_EQ(config->sts_config().scope,
"https://www.newgoogleapis.com/auth/cloud-platform");
EXPECT_EQ(config->sts_config().requested_token_type,
"urn:ietf:params:oauth:token-type:jwt");
EXPECT_EQ(config->sts_config().subject_token_path, "/etc/secret/sajwt.token");
EXPECT_EQ(config->sts_config().subject_token_type,
"urn:ietf:params:oauth:token-type:jwt");
EXPECT_EQ(config->sts_config().actor_token_path, "/etc/secret/sajwt.token");
EXPECT_EQ(config->sts_config().actor_token_type,
"urn:ietf:params:oauth:token-type:jwt");
EXPECT_EQ(config->timeout(), 20 * 1000);
EXPECT_EQ(config->certificate_lifetime(), 400 * 1000);
EXPECT_EQ(config->renewal_grace_period(), 100 * 1000);
EXPECT_EQ(config->key_size(), 1024);
EXPECT_EQ(config->location(),
"https://container.googleapis.com/v1/project/test-project1/"
"locations/test-zone2/clusters/test-cluster3");
}
TEST(GoogleMeshCaConfigTest, Defaults) {
const char* json_str =
"{"
" \"server\": {"
" \"api_type\": \"GRPC\","
" \"grpc_services\": [{"
" \"google_grpc\": {"
" \"call_credentials\": [{"
" \"sts_service\": {"
" \"scope\": "
"\"https://www.googleapis.com/auth/cloud-platform\","
" \"subject_token_path\": \"/etc/secret/sajwt.token\","
" \"subject_token_type\": "
"\"urn:ietf:params:oauth:token-type:jwt\""
" }"
" }]"
" }"
" }]"
" },"
" \"location\": "
"\"https://container.googleapis.com/v1/project/test-project1/locations/"
"test-zone2/clusters/test-cluster3\""
"}";
grpc_error* error = GRPC_ERROR_NONE;
Json json = Json::Parse(json_str, &error);
ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
auto config =
GoogleMeshCaCertificateProviderFactory::Config::Parse(json, &error);
ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
EXPECT_EQ(config->endpoint(), "meshca.googleapis.com");
EXPECT_EQ(config->sts_config().token_exchange_service_uri,
"securetoken.googleapis.com");
EXPECT_EQ(config->sts_config().resource, "");
EXPECT_EQ(config->sts_config().audience, "");
EXPECT_EQ(config->sts_config().scope,
"https://www.googleapis.com/auth/cloud-platform");
EXPECT_EQ(config->sts_config().requested_token_type, "");
EXPECT_EQ(config->sts_config().subject_token_path, "/etc/secret/sajwt.token");
EXPECT_EQ(config->sts_config().subject_token_type,
"urn:ietf:params:oauth:token-type:jwt");
EXPECT_EQ(config->sts_config().actor_token_path, "");
EXPECT_EQ(config->sts_config().actor_token_type, "");
EXPECT_EQ(config->timeout(), 10 * 1000);
EXPECT_EQ(config->certificate_lifetime(), 24 * 60 * 60 * 1000);
EXPECT_EQ(config->renewal_grace_period(), 12 * 60 * 60 * 1000);
EXPECT_EQ(config->key_size(), 2048);
EXPECT_EQ(config->location(),
"https://container.googleapis.com/v1/project/test-project1/"
"locations/test-zone2/clusters/test-cluster3");
}
TEST(GoogleMeshCaConfigTest, WrongExpectedValues) {
const char* json_str =
"{"
" \"server\": {"
" \"api_type\": \"REST\","
" \"grpc_services\": [{"
" \"google_grpc\": {"
" \"call_credentials\": [{"
" \"sts_service\": {"
" \"scope\": "
"\"https://www.googleapis.com/auth/cloud-platform\","
" \"subject_token_path\": \"/etc/secret/sajwt.token\","
" \"subject_token_type\": "
"\"urn:ietf:params:oauth:token-type:jwt\""
" }"
" }]"
" }"
" }]"
" },"
" \"key_type\": \"DSA\","
" \"location\": "
"\"https://container.googleapis.com/v1/project/test-project1/locations/"
"test-zone2/clusters/test-cluster3\""
"}";
grpc_error* error = GRPC_ERROR_NONE;
Json json = Json::Parse(json_str, &error);
ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
auto config =
GoogleMeshCaCertificateProviderFactory::Config::Parse(json, &error);
EXPECT_THAT(
grpc_error_string(error),
::testing::ContainsRegex("field:api_type error:Only GRPC is supported.*"
"field:key_type error:Only RSA is supported"));
GRPC_ERROR_UNREF(error);
}
TEST(GoogleMeshCaConfigTest, WrongTypes) {
const char* json_str =
"{"
" \"server\": {"
" \"api_type\": 123,"
" \"grpc_services\": [{"
" \"google_grpc\": {"
" \"target_uri\": 123,"
" \"call_credentials\": [{"
" \"sts_service\": {"
" \"token_exchange_service_uri\": 123,"
" \"resource\": 123,"
" \"audience\": 123,"
" \"scope\": 123,"
" \"requested_token_type\": 123,"
" \"subject_token_path\": 123,"
" \"subject_token_type\": 123,"
" \"actor_token_path\": 123,"
" \"actor_token_type\": 123"
" }"
" }]"
" },"
" \"timeout\": 20"
" }]"
" },"
" \"certificate_lifetime\": 400,"
" \"renewal_grace_period\": 100,"
" \"key_type\": 123,"
" \"key_size\": \"1024\","
" \"location\": 123"
"}";
grpc_error* error = GRPC_ERROR_NONE;
Json json = Json::Parse(json_str, &error);
ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
auto config =
GoogleMeshCaCertificateProviderFactory::Config::Parse(json, &error);
EXPECT_THAT(
grpc_error_string(error),
::testing::ContainsRegex(
"field:server.*field:api_type error:type should be STRING.*"
"field:grpc_services.*field:google_grpc.*field:target_uri "
"error:type should be STRING.*"
"field:call_credentials.*field:sts_service.*field:token_exchange_"
"service_uri error:type should be STRING.*"
"field:resource error:type should be STRING.*"
"field:audience error:type should be STRING.*"
"field:scope error:type should be STRING.*"
"field:requested_token_type error:type should be STRING.*"
"field:subject_token_path error:type should be STRING.*"
"field:subject_token_type error:type should be STRING.*"
"field:actor_token_path error:type should be STRING.*"
"field:actor_token_type error:type should be STRING.*"
"field:timeout error:type should be STRING of the form given by "
"google.proto.Duration.*"
"field:certificate_lifetime error:type should be STRING of the form "
"given by google.proto.Duration.*"
"field:renewal_grace_period error:type should be STRING of the form "
"given by google.proto.Duration..*"
"field:key_type error:type should be STRING.*"
"field:key_size error:type should be NUMBER.*"
"field:location error:type should be STRING"));
GRPC_ERROR_UNREF(error);
}
TEST(GoogleMeshCaConfigTest, GrpcServicesNotAnArray) {
const char* json_str =
"{"
" \"server\": {"
" \"api_type\": \"GRPC\","
" \"grpc_services\": 123"
" },"
" \"location\": "
"\"https://container.googleapis.com/v1/project/test-project1/locations/"
"test-zone2/clusters/test-cluster3\""
"}";
grpc_error* error = GRPC_ERROR_NONE;
Json json = Json::Parse(json_str, &error);
ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
auto config =
GoogleMeshCaCertificateProviderFactory::Config::Parse(json, &error);
EXPECT_THAT(
grpc_error_string(error),
::testing::ContainsRegex(
"field:server.*field:grpc_services error:type should be ARRAY"));
GRPC_ERROR_UNREF(error);
}
TEST(GoogleMeshCaConfigTest, GoogleGrpcNotAnObject) {
const char* json_str =
"{"
" \"server\": {"
" \"api_type\": \"GRPC\","
" \"grpc_services\": [{"
" \"google_grpc\": 123"
" }]"
" },"
" \"location\": "
"\"https://container.googleapis.com/v1/project/test-project1/locations/"
"test-zone2/clusters/test-cluster3\""
"}";
grpc_error* error = GRPC_ERROR_NONE;
Json json = Json::Parse(json_str, &error);
ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
auto config =
GoogleMeshCaCertificateProviderFactory::Config::Parse(json, &error);
EXPECT_THAT(
grpc_error_string(error),
::testing::ContainsRegex("field:server.*field:grpc_services.*field:"
"google_grpc error:type should be OBJECT"));
GRPC_ERROR_UNREF(error);
}
TEST(GoogleMeshCaConfigTest, CallCredentialsNotAnArray) {
const char* json_str =
"{"
" \"server\": {"
" \"api_type\": \"GRPC\","
" \"grpc_services\": [{"
" \"google_grpc\": {"
" \"call_credentials\": 123"
" }"
" }]"
" },"
" \"location\": "
"\"https://container.googleapis.com/v1/project/test-project1/locations/"
"test-zone2/clusters/test-cluster3\""
"}";
grpc_error* error = GRPC_ERROR_NONE;
Json json = Json::Parse(json_str, &error);
ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
auto config =
GoogleMeshCaCertificateProviderFactory::Config::Parse(json, &error);
EXPECT_THAT(grpc_error_string(error),
::testing::ContainsRegex(
"field:server.*field:grpc_services.*field:google_grpc.*"
"field:call_credentials error:type should be ARRAY"));
GRPC_ERROR_UNREF(error);
}
TEST(GoogleMeshCaConfigTest, StsServiceNotAnObject) {
const char* json_str =
"{"
" \"server\": {"
" \"api_type\": \"GRPC\","
" \"grpc_services\": [{"
" \"google_grpc\": {"
" \"call_credentials\": [{"
" \"sts_service\": 123"
" }]"
" }"
" }]"
" },"
" \"location\": "
"\"https://container.googleapis.com/v1/project/test-project1/locations/"
"test-zone2/clusters/test-cluster3\""
"}";
grpc_error* error = GRPC_ERROR_NONE;
Json json = Json::Parse(json_str, &error);
ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error);
auto config =
GoogleMeshCaCertificateProviderFactory::Config::Parse(json, &error);
EXPECT_THAT(
grpc_error_string(error),
::testing::ContainsRegex(
"field:server.*field:grpc_services.*field:google_grpc.*field:"
"call_credentials.*field:sts_service error:type should be OBJECT"));
GRPC_ERROR_UNREF(error);
}
} // namespace
} // namespace testing
} // namespace grpc_core
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
auto result = RUN_ALL_TESTS();
grpc_shutdown();
return result;
}

@ -1387,6 +1387,8 @@ src/core/ext/xds/certificate_provider_factory.h \
src/core/ext/xds/certificate_provider_registry.cc \
src/core/ext/xds/certificate_provider_registry.h \
src/core/ext/xds/certificate_provider_store.h \
src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc \
src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h \
src/core/ext/xds/xds_api.cc \
src/core/ext/xds/xds_api.h \
src/core/ext/xds/xds_bootstrap.cc \
@ -1696,6 +1698,8 @@ src/core/lib/iomgr/work_serializer.cc \
src/core/lib/iomgr/work_serializer.h \
src/core/lib/json/json.h \
src/core/lib/json/json_reader.cc \
src/core/lib/json/json_util.cc \
src/core/lib/json/json_util.h \
src/core/lib/json/json_writer.cc \
src/core/lib/profiling/basic_timers.cc \
src/core/lib/profiling/stap_timers.cc \

@ -1222,6 +1222,8 @@ src/core/ext/xds/certificate_provider_factory.h \
src/core/ext/xds/certificate_provider_registry.cc \
src/core/ext/xds/certificate_provider_registry.h \
src/core/ext/xds/certificate_provider_store.h \
src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc \
src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h \
src/core/ext/xds/xds_api.cc \
src/core/ext/xds/xds_api.h \
src/core/ext/xds/xds_bootstrap.cc \
@ -1536,6 +1538,8 @@ src/core/lib/iomgr/work_serializer.cc \
src/core/lib/iomgr/work_serializer.h \
src/core/lib/json/json.h \
src/core/lib/json/json_reader.cc \
src/core/lib/json/json_util.cc \
src/core/lib/json/json_util.h \
src/core/lib/json/json_writer.cc \
src/core/lib/profiling/basic_timers.cc \
src/core/lib/profiling/stap_timers.cc \

@ -4503,6 +4503,30 @@
],
"uses_polling": false
},
{
"args": [],
"benchmark": false,
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": true,
"language": "c++",
"name": "google_mesh_ca_certificate_provider_factory_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
],
"uses_polling": true
},
{
"args": [],
"benchmark": false,

Loading…
Cancel
Save