28 #include "absl/memory/memory.h"
29 #include "absl/status/status.h"
30 #include "absl/status/statusor.h"
31 #include "absl/strings/str_cat.h"
32 #include "absl/strings/str_format.h"
33 #include "absl/strings/string_view.h"
34 #include "absl/strings/strip.h"
35 #include "absl/types/optional.h"
72 class GoogleCloud2ProdResolver :
public Resolver {
74 explicit GoogleCloud2ProdResolver(ResolverArgs
args);
76 void StartLocked()
override;
77 void RequestReresolutionLocked()
override;
78 void ResetBackoffLocked()
override;
79 void ShutdownLocked()
override;
83 class MetadataQuery :
public InternallyRefCounted<MetadataQuery> {
85 MetadataQuery(RefCountedPtr<GoogleCloud2ProdResolver> resolver,
87 ~MetadataQuery()
override;
89 void Orphan()
override;
95 virtual void OnDone(GoogleCloud2ProdResolver* resolver,
106 class ZoneQuery :
public MetadataQuery {
108 ZoneQuery(RefCountedPtr<GoogleCloud2ProdResolver> resolver,
112 void OnDone(GoogleCloud2ProdResolver* resolver,
118 class IPv6Query :
public MetadataQuery {
120 IPv6Query(RefCountedPtr<GoogleCloud2ProdResolver> resolver,
124 void OnDone(GoogleCloud2ProdResolver* resolver,
130 void IPv6QueryDone(
bool ipv6_supported);
131 void StartXdsResolver();
152 GoogleCloud2ProdResolver::MetadataQuery::MetadataQuery(
153 RefCountedPtr<GoogleCloud2ProdResolver> resolver,
const char*
path,
162 const_cast<char*
>(
"Google")};
165 auto uri = URI::Create(
"http",
resolver_->metadata_server_name_,
path,
176 RefCountedPtr<grpc_channel_credentials>(
181 GoogleCloud2ProdResolver::MetadataQuery::~MetadataQuery() {
185 void GoogleCloud2ProdResolver::MetadataQuery::Orphan() {
190 void GoogleCloud2ProdResolver::MetadataQuery::OnHttpRequestDone(
192 auto*
self =
static_cast<MetadataQuery*
>(
arg);
196 self->resolver_->work_serializer_->Run(
198 self->OnDone(
self->resolver_.get(), &
self->response_,
error);
208 GoogleCloud2ProdResolver::ZoneQuery::ZoneQuery(
209 RefCountedPtr<GoogleCloud2ProdResolver> resolver,
211 : MetadataQuery(
std::
move(resolver),
"/computeMetadata/v1/instance/zone",
214 void GoogleCloud2ProdResolver::ZoneQuery::OnDone(
220 absl::StrCat(
"error fetching zone from metadata server: ",
222 }
else if (
response->status != 200) {
224 "zone query received non-200 status: %d",
response->status));
227 size_t i = body.find_last_of(
'/');
228 if (
i == body.npos) {
230 absl::StrCat(
"could not parse zone from metadata server: ", body));
238 resolver->ZoneQueryDone(
"");
240 resolver->ZoneQueryDone(
std::move(*zone));
249 GoogleCloud2ProdResolver::IPv6Query::IPv6Query(
250 RefCountedPtr<GoogleCloud2ProdResolver> resolver,
252 : MetadataQuery(
std::
move(resolver),
253 "/computeMetadata/v1/instance/network-interfaces/0/ipv6s",
256 void GoogleCloud2ProdResolver::IPv6Query::OnDone(
271 GoogleCloud2ProdResolver::GoogleCloud2ProdResolver(ResolverArgs
args)
279 args.args,
"grpc.testing.google_c2p_resolver_pretend_running_on_gcp",
281 bool running_on_gcp =
283 if (!running_on_gcp ||
288 UniquePtr<char>(
gpr_getenv(
"GRPC_XDS_BOOTSTRAP")) !=
nullptr ||
289 UniquePtr<char>(
gpr_getenv(
"GRPC_XDS_BOOTSTRAP_CONFIG")) !=
nullptr) {
299 const char* test_only_metadata_server_override =
302 "grpc.testing.google_c2p_resolver_metadata_server_override");
303 if (test_only_metadata_server_override !=
nullptr &&
304 strlen(test_only_metadata_server_override) > 0) {
314 void GoogleCloud2ProdResolver::StartLocked() {
324 void GoogleCloud2ProdResolver::RequestReresolutionLocked() {
330 void GoogleCloud2ProdResolver::ResetBackoffLocked() {
336 void GoogleCloud2ProdResolver::ShutdownLocked() {
343 void GoogleCloud2ProdResolver::ZoneQueryDone(
std::string zone) {
349 void GoogleCloud2ProdResolver::IPv6QueryDone(
bool ipv6_supported) {
355 void GoogleCloud2ProdResolver::StartXdsResolver() {
360 std::random_device rd;
361 std::mt19937 mt(rd());
362 std::uniform_int_distribution<uint64_t> dist(1,
UINT64_MAX);
363 Json::Object node = {
366 if (!
zone_->empty()) {
367 node[
"locality"] = Json::Object{
372 node[
"metadata"] = Json::Object{
373 {
"TRAFFICDIRECTOR_DIRECTPATH_C2P_IPV6_CAPABLE",
true},
377 UniquePtr<char> override_server(
378 gpr_getenv(
"GRPC_TEST_ONLY_GOOGLE_C2P_RESOLVER_TRAFFIC_DIRECTOR_URI"));
380 override_server !=
nullptr && strlen(override_server.get()) > 0
381 ? override_server.get()
382 :
"directpath-pa.googleapis.com";
383 Json xds_server = Json::Array{
389 {
"type",
"google_default"},
392 {
"server_features", Json::Array{
"xds_v3"}},
395 Json bootstrap = Json::Object{
396 {
"xds_servers", xds_server},
399 {
"traffic-director-c2p.xds.googleapis.com",
416 class GoogleCloud2ProdResolverFactory :
public ResolverFactory {
421 return "google-c2p-experimental";
424 bool IsValidUri(
const URI& uri)
const override {
432 OrphanablePtr<Resolver> CreateResolver(ResolverArgs
args)
const override {
433 if (!IsValidUri(
args.uri))
return nullptr;
434 return MakeOrphanable<GoogleCloud2ProdResolver>(
std::move(
args));
441 builder->resolver_registry()->RegisterResolverFactory(
442 absl::make_unique<GoogleCloud2ProdResolverFactory>());