diff --git a/BUILD b/BUILD
index e1d4d322338..023b1cede4b 100644
--- a/BUILD
+++ b/BUILD
@@ -2755,6 +2755,7 @@ grpc_cc_library(
"src/core/ext/xds/xds_api.cc",
"src/core/ext/xds/xds_bootstrap.cc",
"src/core/ext/xds/xds_certificate_provider.cc",
+ "src/core/ext/xds/xds_channel_creds.cc",
"src/core/ext/xds/xds_client.cc",
"src/core/ext/xds/xds_client_stats.cc",
"src/core/ext/xds/xds_cluster.cc",
@@ -2779,6 +2780,7 @@ grpc_cc_library(
"src/core/ext/xds/xds_bootstrap.h",
"src/core/ext/xds/xds_certificate_provider.h",
"src/core/ext/xds/xds_channel_args.h",
+ "src/core/ext/xds/xds_channel_creds.h",
"src/core/ext/xds/xds_client.h",
"src/core/ext/xds/xds_client_stats.h",
"src/core/ext/xds/xds_cluster.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4a1a9e6adae..9a91220ed0d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1030,6 +1030,7 @@ if(gRPC_BUILD_TESTS)
endif()
add_dependencies(buildtests_cxx xds_bootstrap_test)
add_dependencies(buildtests_cxx xds_certificate_provider_test)
+ add_dependencies(buildtests_cxx xds_channel_creds_registry_test)
add_dependencies(buildtests_cxx xds_credentials_end2end_test)
add_dependencies(buildtests_cxx xds_credentials_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
@@ -1861,6 +1862,7 @@ add_library(grpc
src/core/ext/xds/xds_api.cc
src/core/ext/xds/xds_bootstrap.cc
src/core/ext/xds/xds_certificate_provider.cc
+ src/core/ext/xds/xds_channel_creds.cc
src/core/ext/xds/xds_channel_stack_modifier.cc
src/core/ext/xds/xds_client.cc
src/core/ext/xds/xds_client_stats.cc
@@ -16724,6 +16726,41 @@ target_link_libraries(xds_certificate_provider_test
)
+endif()
+if(gRPC_BUILD_TESTS)
+
+add_executable(xds_channel_creds_registry_test
+ test/core/xds/xds_channel_creds_registry_test.cc
+ third_party/googletest/googletest/src/gtest-all.cc
+ third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+target_include_directories(xds_channel_creds_registry_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_XXHASH_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(xds_channel_creds_registry_test
+ ${_gRPC_PROTOBUF_LIBRARIES}
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ grpc_test_util
+)
+
+
endif()
if(gRPC_BUILD_TESTS)
diff --git a/Makefile b/Makefile
index 0cae2f63366..52e7383c83d 100644
--- a/Makefile
+++ b/Makefile
@@ -1348,6 +1348,7 @@ LIBGRPC_SRC = \
src/core/ext/xds/xds_api.cc \
src/core/ext/xds/xds_bootstrap.cc \
src/core/ext/xds/xds_certificate_provider.cc \
+ src/core/ext/xds/xds_channel_creds.cc \
src/core/ext/xds/xds_channel_stack_modifier.cc \
src/core/ext/xds/xds_client.cc \
src/core/ext/xds/xds_client_stats.cc \
@@ -2961,6 +2962,7 @@ src/core/ext/xds/file_watcher_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_certificate_provider.cc: $(OPENSSL_DEP)
+src/core/ext/xds/xds_channel_creds.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_channel_stack_modifier.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_client.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_client_stats.cc: $(OPENSSL_DEP)
diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml
index f230940ac01..70f07694113 100644
--- a/build_autogenerated.yaml
+++ b/build_autogenerated.yaml
@@ -710,6 +710,7 @@ libs:
- src/core/ext/xds/xds_bootstrap.h
- src/core/ext/xds/xds_certificate_provider.h
- src/core/ext/xds/xds_channel_args.h
+ - src/core/ext/xds/xds_channel_creds.h
- src/core/ext/xds/xds_channel_stack_modifier.h
- src/core/ext/xds/xds_client.h
- src/core/ext/xds/xds_client_stats.h
@@ -1314,6 +1315,7 @@ libs:
- src/core/ext/xds/xds_api.cc
- src/core/ext/xds/xds_bootstrap.cc
- src/core/ext/xds/xds_certificate_provider.cc
+ - src/core/ext/xds/xds_channel_creds.cc
- src/core/ext/xds/xds_channel_stack_modifier.cc
- src/core/ext/xds/xds_client.cc
- src/core/ext/xds/xds_client_stats.cc
@@ -8380,6 +8382,15 @@ targets:
- test/core/xds/xds_certificate_provider_test.cc
deps:
- grpc_test_util
+- name: xds_channel_creds_registry_test
+ gtest: true
+ build: test
+ language: c++
+ headers: []
+ src:
+ - test/core/xds/xds_channel_creds_registry_test.cc
+ deps:
+ - grpc_test_util
- name: xds_credentials_end2end_test
gtest: true
build: test
diff --git a/config.m4 b/config.m4
index 2f28ef042e3..e15fa572fe1 100644
--- a/config.m4
+++ b/config.m4
@@ -366,6 +366,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/xds/xds_api.cc \
src/core/ext/xds/xds_bootstrap.cc \
src/core/ext/xds/xds_certificate_provider.cc \
+ src/core/ext/xds/xds_channel_creds.cc \
src/core/ext/xds/xds_channel_stack_modifier.cc \
src/core/ext/xds/xds_client.cc \
src/core/ext/xds/xds_client_stats.cc \
diff --git a/config.w32 b/config.w32
index 4c713798708..0c88a5e6fe8 100644
--- a/config.w32
+++ b/config.w32
@@ -332,6 +332,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\xds\\xds_api.cc " +
"src\\core\\ext\\xds\\xds_bootstrap.cc " +
"src\\core\\ext\\xds\\xds_certificate_provider.cc " +
+ "src\\core\\ext\\xds\\xds_channel_creds.cc " +
"src\\core\\ext\\xds\\xds_channel_stack_modifier.cc " +
"src\\core\\ext\\xds\\xds_client.cc " +
"src\\core\\ext\\xds\\xds_client_stats.cc " +
diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec
index 94238b25d11..91a954408b3 100644
--- a/gRPC-C++.podspec
+++ b/gRPC-C++.podspec
@@ -555,6 +555,7 @@ Pod::Spec.new do |s|
'src/core/ext/xds/xds_bootstrap.h',
'src/core/ext/xds/xds_certificate_provider.h',
'src/core/ext/xds/xds_channel_args.h',
+ 'src/core/ext/xds/xds_channel_creds.h',
'src/core/ext/xds/xds_channel_stack_modifier.h',
'src/core/ext/xds/xds_client.h',
'src/core/ext/xds/xds_client_stats.h',
@@ -1287,6 +1288,7 @@ Pod::Spec.new do |s|
'src/core/ext/xds/xds_bootstrap.h',
'src/core/ext/xds/xds_certificate_provider.h',
'src/core/ext/xds/xds_channel_args.h',
+ 'src/core/ext/xds/xds_channel_creds.h',
'src/core/ext/xds/xds_channel_stack_modifier.h',
'src/core/ext/xds/xds_client.h',
'src/core/ext/xds/xds_client_stats.h',
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 04ccf6e457f..4c2980404a2 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -820,6 +820,8 @@ Pod::Spec.new do |s|
'src/core/ext/xds/xds_certificate_provider.cc',
'src/core/ext/xds/xds_certificate_provider.h',
'src/core/ext/xds/xds_channel_args.h',
+ 'src/core/ext/xds/xds_channel_creds.cc',
+ 'src/core/ext/xds/xds_channel_creds.h',
'src/core/ext/xds/xds_channel_stack_modifier.cc',
'src/core/ext/xds/xds_channel_stack_modifier.h',
'src/core/ext/xds/xds_client.cc',
@@ -1828,6 +1830,7 @@ Pod::Spec.new do |s|
'src/core/ext/xds/xds_bootstrap.h',
'src/core/ext/xds/xds_certificate_provider.h',
'src/core/ext/xds/xds_channel_args.h',
+ 'src/core/ext/xds/xds_channel_creds.h',
'src/core/ext/xds/xds_channel_stack_modifier.h',
'src/core/ext/xds/xds_client.h',
'src/core/ext/xds/xds_client_stats.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index 9b40c216d4b..154971f7d8e 100644
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -739,6 +739,8 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/xds/xds_certificate_provider.cc )
s.files += %w( src/core/ext/xds/xds_certificate_provider.h )
s.files += %w( src/core/ext/xds/xds_channel_args.h )
+ s.files += %w( src/core/ext/xds/xds_channel_creds.cc )
+ s.files += %w( src/core/ext/xds/xds_channel_creds.h )
s.files += %w( src/core/ext/xds/xds_channel_stack_modifier.cc )
s.files += %w( src/core/ext/xds/xds_channel_stack_modifier.h )
s.files += %w( src/core/ext/xds/xds_client.cc )
diff --git a/grpc.gyp b/grpc.gyp
index 7dead4dcfc3..abd8ed7d8e2 100644
--- a/grpc.gyp
+++ b/grpc.gyp
@@ -796,6 +796,7 @@
'src/core/ext/xds/xds_api.cc',
'src/core/ext/xds/xds_bootstrap.cc',
'src/core/ext/xds/xds_certificate_provider.cc',
+ 'src/core/ext/xds/xds_channel_creds.cc',
'src/core/ext/xds/xds_channel_stack_modifier.cc',
'src/core/ext/xds/xds_client.cc',
'src/core/ext/xds/xds_client_stats.cc',
diff --git a/package.xml b/package.xml
index 9588e318b85..9090ab25a1a 100644
--- a/package.xml
+++ b/package.xml
@@ -719,6 +719,8 @@
+
+
diff --git a/src/core/ext/xds/xds_bootstrap.cc b/src/core/ext/xds/xds_bootstrap.cc
index 4111406b11d..81d86fb5fff 100644
--- a/src/core/ext/xds/xds_bootstrap.cc
+++ b/src/core/ext/xds/xds_bootstrap.cc
@@ -28,8 +28,11 @@
#include "absl/strings/str_join.h"
#include "absl/strings/string_view.h"
+#include
+
#include "src/core/ext/xds/certificate_provider_registry.h"
#include "src/core/ext/xds/xds_api.h"
+#include "src/core/ext/xds/xds_channel_creds.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/load_file.h"
@@ -100,39 +103,6 @@ grpc_error_handle ParseChannelCredsArray(const Json::Array& json,
} // namespace
-//
-// XdsChannelCredsRegistry
-//
-
-bool XdsChannelCredsRegistry::IsSupported(const std::string& creds_type) {
- return creds_type == "google_default" || creds_type == "insecure" ||
- creds_type == "fake";
-}
-
-bool XdsChannelCredsRegistry::IsValidConfig(const std::string& /*creds_type*/,
- const Json& /*config*/) {
- // Currently, none of the creds types actually take a config, but we
- // ignore whatever might be specified in the bootstrap file for
- // forward compatibility reasons.
- return true;
-}
-
-RefCountedPtr
-XdsChannelCredsRegistry::MakeChannelCreds(const std::string& creds_type,
- const Json& /*config*/) {
- if (creds_type == "google_default") {
- return RefCountedPtr(
- grpc_google_default_credentials_create(nullptr));
- } else if (creds_type == "insecure") {
- return RefCountedPtr(
- grpc_insecure_credentials_create());
- } else if (creds_type == "fake") {
- return RefCountedPtr(
- grpc_fake_transport_security_credentials_create());
- }
- return nullptr;
-}
-
//
// XdsBootstrap::XdsServer
//
diff --git a/src/core/ext/xds/xds_bootstrap.h b/src/core/ext/xds/xds_bootstrap.h
index 63bb32334c8..10511e5e9ff 100644
--- a/src/core/ext/xds/xds_bootstrap.h
+++ b/src/core/ext/xds/xds_bootstrap.h
@@ -39,14 +39,6 @@ namespace grpc_core {
class XdsClient;
-class XdsChannelCredsRegistry {
- public:
- static bool IsSupported(const std::string& creds_type);
- static bool IsValidConfig(const std::string& creds_type, const Json& config);
- static RefCountedPtr MakeChannelCreds(
- const std::string& creds_type, const Json& config);
-};
-
class XdsBootstrap {
public:
struct Node {
diff --git a/src/core/ext/xds/xds_channel_creds.cc b/src/core/ext/xds/xds_channel_creds.cc
new file mode 100644
index 00000000000..761351c0cd1
--- /dev/null
+++ b/src/core/ext/xds/xds_channel_creds.cc
@@ -0,0 +1,108 @@
+//
+// Copyright 2019 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
+
+#include "src/core/ext/xds/xds_channel_creds.h"
+
+#include "src/core/lib/security/credentials/fake/fake_credentials.h"
+
+namespace grpc_core {
+
+namespace {
+
+using ChannelCredsMap =
+ std::map>;
+ChannelCredsMap* g_creds = nullptr;
+
+} // namespace
+
+//
+// XdsChannelCredsImpl implementations for default-supported cred types.
+//
+
+class GoogleDefaultXdsChannelCredsImpl : public XdsChannelCredsImpl {
+ public:
+ absl::string_view creds_type() const override { return "google_default"; }
+ RefCountedPtr CreateXdsChannelCreds(
+ const Json& /*config*/) const override {
+ return RefCountedPtr(
+ grpc_google_default_credentials_create(nullptr));
+ }
+ bool IsValidConfig(const Json& /*config*/) const override { return true; }
+};
+
+class InsecureXdsChannelCredsImpl : public XdsChannelCredsImpl {
+ public:
+ absl::string_view creds_type() const override { return "insecure"; }
+ RefCountedPtr CreateXdsChannelCreds(
+ const Json& /*config*/) const override {
+ return RefCountedPtr(
+ grpc_insecure_credentials_create());
+ }
+ bool IsValidConfig(const Json& /*config*/) const override { return true; }
+};
+
+class FakeXdsChannelCredsImpl : public XdsChannelCredsImpl {
+ public:
+ absl::string_view creds_type() const override { return "fake"; }
+ RefCountedPtr CreateXdsChannelCreds(
+ const Json& /*config*/) const override {
+ return RefCountedPtr(
+ grpc_fake_transport_security_credentials_create());
+ }
+ bool IsValidConfig(const Json& /*config*/) const override { return true; }
+};
+
+//
+// XdsChannelCredsRegistry
+//
+
+bool XdsChannelCredsRegistry::IsSupported(const std::string& creds_type) {
+ return g_creds->find(creds_type) != g_creds->end();
+}
+
+bool XdsChannelCredsRegistry::IsValidConfig(const std::string& creds_type,
+ const Json& config) {
+ const auto iter = g_creds->find(creds_type);
+ if (iter == g_creds->cend()) return false;
+ return iter->second->IsValidConfig(config);
+}
+
+RefCountedPtr
+XdsChannelCredsRegistry::CreateXdsChannelCreds(const std::string& creds_type,
+ const Json& config) {
+ const auto iter = g_creds->find(creds_type);
+ if (iter == g_creds->cend()) return nullptr;
+ return iter->second->CreateXdsChannelCreds(config);
+}
+
+void XdsChannelCredsRegistry::Init() {
+ g_creds = new ChannelCredsMap();
+ RegisterXdsChannelCreds(
+ absl::make_unique());
+ RegisterXdsChannelCreds(absl::make_unique());
+ RegisterXdsChannelCreds(absl::make_unique());
+}
+
+void XdsChannelCredsRegistry::Shutdown() { delete g_creds; }
+
+void XdsChannelCredsRegistry::RegisterXdsChannelCreds(
+ std::unique_ptr creds) {
+ (*g_creds)[creds->creds_type()] = std::move(creds);
+}
+
+} // namespace grpc_core
diff --git a/src/core/ext/xds/xds_channel_creds.h b/src/core/ext/xds/xds_channel_creds.h
new file mode 100644
index 00000000000..4d5668eebe4
--- /dev/null
+++ b/src/core/ext/xds/xds_channel_creds.h
@@ -0,0 +1,50 @@
+//
+// Copyright 2022 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_XDS_CHANNEL_CREDS_H
+#define GRPC_CORE_EXT_XDS_XDS_CHANNEL_CREDS_H
+
+#include
+
+#include "src/core/lib/json/json.h"
+#include "src/core/lib/security/credentials/credentials.h"
+
+namespace grpc_core {
+
+class XdsChannelCredsImpl {
+ public:
+ virtual ~XdsChannelCredsImpl() {}
+ virtual absl::string_view creds_type() const = 0;
+ virtual bool IsValidConfig(const Json& config) const = 0;
+ virtual RefCountedPtr CreateXdsChannelCreds(
+ const Json& config) const = 0;
+};
+
+class XdsChannelCredsRegistry {
+ public:
+ static bool IsSupported(const std::string& creds_type);
+ static bool IsValidConfig(const std::string& creds_type, const Json& config);
+ static RefCountedPtr CreateXdsChannelCreds(
+ const std::string& creds_type, const Json& config);
+ static void Init();
+ static void Shutdown();
+ static void RegisterXdsChannelCreds(
+ std::unique_ptr creds);
+};
+
+} // namespace grpc_core
+
+#endif // GRPC_CORE_EXT_XDS_XDS_CHANNEL_CREDS_H
diff --git a/src/core/ext/xds/xds_client.cc b/src/core/ext/xds/xds_client.cc
index fe63802be98..5660dfbb5ad 100644
--- a/src/core/ext/xds/xds_client.cc
+++ b/src/core/ext/xds/xds_client.cc
@@ -36,6 +36,7 @@
#include "src/core/ext/xds/xds_api.h"
#include "src/core/ext/xds/xds_bootstrap.h"
#include "src/core/ext/xds/xds_channel_args.h"
+#include "src/core/ext/xds/xds_channel_creds.h"
#include "src/core/ext/xds/xds_client_stats.h"
#include "src/core/ext/xds/xds_cluster.h"
#include "src/core/ext/xds/xds_endpoint.h"
@@ -511,8 +512,8 @@ namespace {
grpc_channel* CreateXdsChannel(grpc_channel_args* args,
const XdsBootstrap::XdsServer& server) {
RefCountedPtr channel_creds =
- XdsChannelCredsRegistry::MakeChannelCreds(server.channel_creds_type,
- server.channel_creds_config);
+ XdsChannelCredsRegistry::CreateXdsChannelCreds(
+ server.channel_creds_type, server.channel_creds_config);
return grpc_secure_channel_create(channel_creds.get(),
server.server_uri.c_str(), args, nullptr);
}
@@ -2300,6 +2301,7 @@ std::string XdsClient::DumpClientConfigBinary() {
void XdsClientGlobalInit() {
g_mu = new Mutex;
XdsHttpFilterRegistry::Init();
+ XdsChannelCredsRegistry::Init();
}
// TODO(roth): Find a better way to clear the fallback config that does
@@ -2309,6 +2311,7 @@ void XdsClientGlobalShutdown() ABSL_NO_THREAD_SAFETY_ANALYSIS {
g_fallback_bootstrap_config = nullptr;
delete g_mu;
g_mu = nullptr;
+ XdsChannelCredsRegistry::Shutdown();
XdsHttpFilterRegistry::Shutdown();
}
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 91f76908c1d..70ad5dc6c4f 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -341,6 +341,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/xds/xds_api.cc',
'src/core/ext/xds/xds_bootstrap.cc',
'src/core/ext/xds/xds_certificate_provider.cc',
+ 'src/core/ext/xds/xds_channel_creds.cc',
'src/core/ext/xds/xds_channel_stack_modifier.cc',
'src/core/ext/xds/xds_client.cc',
'src/core/ext/xds/xds_client_stats.cc',
diff --git a/test/core/xds/BUILD b/test/core/xds/BUILD
index 1ef10d6cceb..01fbea39c0c 100644
--- a/test/core/xds/BUILD
+++ b/test/core/xds/BUILD
@@ -96,3 +96,18 @@ grpc_cc_test(
"//test/core/util:grpc_test_util",
],
)
+
+grpc_cc_test(
+ name = "xds_channel_creds_registry_test",
+ srcs = ["xds_channel_creds_registry_test.cc"],
+ external_deps = [
+ "gtest",
+ ],
+ language = "C++",
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//:grpc_secure",
+ "//test/core/util:grpc_test_util",
+ ],
+)
diff --git a/test/core/xds/xds_channel_creds_registry_test.cc b/test/core/xds/xds_channel_creds_registry_test.cc
new file mode 100644
index 00000000000..d27b5c94f05
--- /dev/null
+++ b/test/core/xds/xds_channel_creds_registry_test.cc
@@ -0,0 +1,79 @@
+//
+//
+// Copyright 2022 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
+#include
+
+#include
+
+#include "src/core/ext/xds/xds_bootstrap.h"
+#include "src/core/ext/xds/xds_channel_creds.h"
+#include "src/core/lib/security/credentials/fake/fake_credentials.h"
+#include "test/core/util/test_config.h"
+
+namespace grpc_core {
+namespace testing {
+namespace {
+
+class TestXdsChannelCredsImpl : public XdsChannelCredsImpl {
+ public:
+ absl::string_view creds_type() const override { return "test"; }
+ bool IsValidConfig(const Json& /*config*/) const override { return true; }
+ RefCountedPtr CreateXdsChannelCreds(
+ const Json& /*config*/) const override {
+ return RefCountedPtr(
+ grpc_fake_transport_security_credentials_create());
+ }
+};
+
+TEST(XdsChannelCredsRegistryTest, DefaultCreds) { // Default creds.
+ EXPECT_TRUE(XdsChannelCredsRegistry::IsSupported("google_default"));
+ EXPECT_TRUE(XdsChannelCredsRegistry::IsSupported("insecure"));
+ EXPECT_TRUE(XdsChannelCredsRegistry::IsSupported("fake"));
+
+ // Non-default creds.
+ EXPECT_EQ(XdsChannelCredsRegistry::CreateXdsChannelCreds("test", Json()),
+ nullptr);
+ EXPECT_EQ(XdsChannelCredsRegistry::CreateXdsChannelCreds("", Json()),
+ nullptr);
+}
+
+TEST(XdsChannelCredsRegistryTest, Register) {
+ // Before registration.
+ EXPECT_FALSE(XdsChannelCredsRegistry::IsSupported("test"));
+ EXPECT_EQ(XdsChannelCredsRegistry::CreateXdsChannelCreds("test", Json()),
+ nullptr);
+
+ // Registration.
+ XdsChannelCredsRegistry::RegisterXdsChannelCreds(
+ absl::make_unique());
+ EXPECT_NE(XdsChannelCredsRegistry::CreateXdsChannelCreds("test", Json()),
+ nullptr);
+}
+
+} // 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();
+ return result;
+}
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 093e0db1775..c55f47006c7 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -1718,6 +1718,8 @@ src/core/ext/xds/xds_bootstrap.h \
src/core/ext/xds/xds_certificate_provider.cc \
src/core/ext/xds/xds_certificate_provider.h \
src/core/ext/xds/xds_channel_args.h \
+src/core/ext/xds/xds_channel_creds.cc \
+src/core/ext/xds/xds_channel_creds.h \
src/core/ext/xds/xds_channel_stack_modifier.cc \
src/core/ext/xds/xds_channel_stack_modifier.h \
src/core/ext/xds/xds_client.cc \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 03b3a9ed4b5..8ac97d3a429 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -1512,6 +1512,8 @@ src/core/ext/xds/xds_bootstrap.h \
src/core/ext/xds/xds_certificate_provider.cc \
src/core/ext/xds/xds_certificate_provider.h \
src/core/ext/xds/xds_channel_args.h \
+src/core/ext/xds/xds_channel_creds.cc \
+src/core/ext/xds/xds_channel_creds.h \
src/core/ext/xds/xds_channel_stack_modifier.cc \
src/core/ext/xds/xds_channel_stack_modifier.h \
src/core/ext/xds/xds_client.cc \
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index e6aeeff3019..b03d7fa57fc 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -7401,6 +7401,30 @@
],
"uses_polling": true
},
+ {
+ "args": [],
+ "benchmark": false,
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "gtest": true,
+ "language": "c++",
+ "name": "xds_channel_creds_registry_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "uses_polling": true
+ },
{
"args": [],
"benchmark": false,