Skip to content

Commit

Permalink
Add x-goog-user-proj header for sts credential (#152)
Browse files Browse the repository at this point in the history
* add x-google-user-proj header

Signed-off-by: Pengyuan Bian <bianpengyuan@google.com>

* clean up log

Signed-off-by: Pengyuan Bian <bianpengyuan@google.com>
  • Loading branch information
bianpengyuan authored Feb 19, 2020
1 parent e0ecba3 commit 37dbbd4
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 18 deletions.
33 changes: 19 additions & 14 deletions api/wasm/cpp/proxy_wasm_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,9 @@ class RootContext : public ContextBase {
const std::string root_id_;
std::unordered_map<uint32_t, HttpCallCallback> http_calls_;
std::unordered_map<uint32_t, GrpcSimpleCallCallback> simple_grpc_calls_;
std::unique_ptr<GrpcCallHandlerBase> cur_grpc_call_;
std::unordered_map<uint32_t, std::unique_ptr<GrpcCallHandlerBase>> grpc_calls_;
std::unique_ptr<GrpcStreamHandlerBase> cur_grpc_stream_;
std::unordered_map<uint32_t, std::unique_ptr<GrpcStreamHandlerBase>> grpc_streams_;
};

Expand Down Expand Up @@ -1234,19 +1236,16 @@ inline void GrpcStreamHandlerBase::send(StringView message, bool end_of_stream)
}
}

inline void RootContext::onGrpcCreateInitialMetadata(uint32_t token) {
inline void RootContext::onGrpcCreateInitialMetadata(uint32_t) {
{
auto it = grpc_calls_.find(token);
if (it != grpc_calls_.end()) {
it->second->onCreateInitialMetadata();
if (cur_grpc_call_ != nullptr) {
cur_grpc_call_->onCreateInitialMetadata();
return;
}
}
{
auto it = grpc_streams_.find(token);
if (it != grpc_streams_.end()) {
it->second->onCreateInitialMetadata();
return;
if (cur_grpc_stream_ != nullptr) {
cur_grpc_stream_->onCreateInitialMetadata();
}
}
}
Expand Down Expand Up @@ -1345,26 +1344,32 @@ inline bool RootContext::grpcCallHandler(StringView service, StringView service_
const google::protobuf::MessageLite& request,
uint32_t timeout_milliseconds,
std::unique_ptr<GrpcCallHandlerBase> handler) {
cur_grpc_call_ = std::move(handler);
auto token = grpcCall(service, service_name, method_name, request, timeout_milliseconds);
if (token) {
handler->token_ = token;
handler->context_ = this;
grpc_calls_[token] = std::move(handler);
cur_grpc_call_->token_ = token;
cur_grpc_call_->context_ = this;
grpc_calls_[token] = std::move(cur_grpc_call_);
cur_grpc_call_ = nullptr;
return true;
}
cur_grpc_call_ = nullptr;
return false;
}

inline bool RootContext::grpcStreamHandler(StringView service, StringView service_name,
StringView method_name,
std::unique_ptr<GrpcStreamHandlerBase> handler) {
cur_grpc_stream_ = std::move(handler);
auto token = grpcStream(service, service_name, method_name);
if (token) {
handler->token_ = token;
handler->context_ = this;
grpc_streams_[token] = std::move(handler);
cur_grpc_stream_->token_ = token;
cur_grpc_stream_->context_ = this;
grpc_streams_[token] = std::move(cur_grpc_stream_);
cur_grpc_stream_ = nullptr;
return true;
}
cur_grpc_stream_ = nullptr;
return false;
}

Expand Down
60 changes: 56 additions & 4 deletions source/extensions/tracers/opencensus/opencensus_tracer_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,39 @@ Tracing::SpanPtr Span::spawnChild(const Tracing::Config& /*config*/, const std::

void Span::setSampled(bool sampled) { span_.AddAnnotation("setSampled", {{"sampled", sampled}}); }

class GoogleUserProjHeaderInterceptor : public grpc::experimental::Interceptor {
public:
GoogleUserProjHeaderInterceptor(const std::string& project_id) : project_id_(project_id) {}

virtual void Intercept(grpc::experimental::InterceptorBatchMethods* methods) {
if (methods->QueryInterceptionHookPoint(
grpc::experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) {
auto* metadata_map = methods->GetSendInitialMetadata();
if (metadata_map != nullptr) {
metadata_map->insert(std::make_pair("x-goog-user-project", project_id_));
}
}
methods->Proceed();
}

private:
const std::string& project_id_;
};

class GoogleUserProjHeaderInterceptorFactory
: public grpc::experimental::ClientInterceptorFactoryInterface {
public:
GoogleUserProjHeaderInterceptorFactory(const std::string& project_id) : project_id_(project_id) {}

virtual grpc::experimental::Interceptor*
CreateClientInterceptor(grpc::experimental::ClientRpcInfo*) override {
return new GoogleUserProjHeaderInterceptor(project_id_);
}

private:
std::string project_id_;
};

} // namespace

Driver::Driver(const envoy::config::trace::v2::OpenCensusConfig& oc_config,
Expand All @@ -250,8 +283,22 @@ Driver::Driver(const envoy::config::trace::v2::OpenCensusConfig& oc_config,
sts_port = port_iter->second.string_value();
}
if (oc_config.stackdriver_exporter_enabled()) {
// Try get GCP project ID from node metadata.
std::string project_id;
auto platform_md_iter = node_metadata.fields().find("PLATFORM_METADATA");
if (platform_md_iter != node_metadata.fields().end()) {
auto platform_md = platform_md_iter->second.struct_value();
auto proj_id_iter = platform_md.fields().find("gcp_project");
if (proj_id_iter != platform_md.fields().end()) {
project_id = proj_id_iter->second.string_value();
}
}
::opencensus::exporters::trace::StackdriverOptions opts;
opts.project_id = oc_config.stackdriver_project_id();
if (!oc_config.stackdriver_project_id().empty()) {
opts.project_id = oc_config.stackdriver_project_id();
} else if (!project_id.empty()) {
opts.project_id = project_id;
}
if (!oc_config.stackdriver_address().empty()) {
auto channel =
grpc::CreateChannel(oc_config.stackdriver_address(), grpc::InsecureChannelCredentials());
Expand All @@ -267,9 +314,14 @@ Driver::Driver(const envoy::config::trace::v2::OpenCensusConfig& oc_config,
ssl_creds_options.pem_root_certs =
api.fileSystem().fileReadToEnd("/etc/ssl/certs/ca-certificates.crt");
auto channel_creds = grpc::SslCredentials(ssl_creds_options);
auto channel =
::grpc::CreateChannel("cloudtrace.googleapis.com",
grpc::CompositeChannelCredentials(channel_creds, call_creds));
// Create an custom channel which includes an interceptor that inject user project header.
grpc::ChannelArguments args;
std::vector<std::unique_ptr<grpc::experimental::ClientInterceptorFactoryInterface>> creators;
creators.push_back(std::unique_ptr<GoogleUserProjHeaderInterceptorFactory>(
new GoogleUserProjHeaderInterceptorFactory(project_id)));
auto channel = ::grpc::experimental::CreateCustomChannelWithInterceptors(
"cloudtrace.googleapis.com", grpc::CompositeChannelCredentials(channel_creds, call_creds),
args, std::move(creators));
opts.trace_service_stub = ::google::devtools::cloudtrace::v2::TraceService::NewStub(channel);
}
::opencensus::exporters::trace::StackdriverExporter::Register(std::move(opts));
Expand Down

0 comments on commit 37dbbd4

Please sign in to comment.