Skip to content

Commit

Permalink
Support export via TLS (fix #12).
Browse files Browse the repository at this point in the history
  • Loading branch information
Nikita Vakula authored and p-pautov committed Nov 21, 2024
1 parent da2e4eb commit 6c1659a
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 8 deletions.
4 changes: 2 additions & 2 deletions src/batch_exporter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,10 @@ class BatchExporter {
int attrSize{0};
};

BatchExporter(StrView target,
BatchExporter(StrView target, bool ssl, const std::string& trustedCert,
size_t batchSize, size_t batchCount,
const std::map<StrView, StrView>& resourceAttrs) :
batchSize(batchSize), client(std::string(target))
batchSize(batchSize), client(std::string(target), ssl, trustedCert)
{
free.reserve(batchCount);
while (batchCount-- > 0) {
Expand Down
45 changes: 42 additions & 3 deletions src/http_module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include "trace_context.hpp"
#include "batch_exporter.hpp"

#include <fstream>

extern ngx_module_t gHttpModule;

namespace {
Expand All @@ -26,6 +28,8 @@ struct MainConfBase {

struct MainConf : MainConfBase {
std::map<StrView, StrView> resourceAttrs;
bool ssl;
std::string trustedCert;
};

struct SpanAttr {
Expand All @@ -44,6 +48,7 @@ struct LocationConf {
char* setExporter(ngx_conf_t* cf, ngx_command_t* cmd, void* conf);
char* addResourceAttr(ngx_conf_t* cf, ngx_command_t* cmd, void* conf);
char* addSpanAttr(ngx_conf_t* cf, ngx_command_t* cmd, void* conf);
char* setTrustedCertificate(ngx_conf_t* cf, ngx_command_t* cmd, void* conf);

namespace Propagation {

Expand Down Expand Up @@ -111,6 +116,10 @@ ngx_command_t gExporterCommands[] = {
0,
offsetof(MainConfBase, endpoint) },

{ ngx_string("trusted_certificate"),
NGX_CONF_TAKE1,
setTrustedCertificate },

{ ngx_string("interval"),
NGX_CONF_TAKE1,
ngx_conf_set_msec_slot,
Expand Down Expand Up @@ -569,6 +578,8 @@ ngx_int_t initWorkerProcess(ngx_cycle_t* cycle)
try {
gExporter.reset(new BatchExporter(
toStrView(mcf->endpoint),
mcf->ssl,
mcf->trustedCert,
mcf->batchSize,
mcf->batchCount,
mcf->resourceAttrs));
Expand Down Expand Up @@ -671,9 +682,7 @@ char* setExporter(ngx_conf_t* cf, ngx_command_t* cmd, void* conf)
}

if (iremovePrefix(&mcf->endpoint, "https://")) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"otel_exporter\" doesn't support \"https\" endpoints");
return (char*)NGX_CONF_ERROR;
mcf->ssl = true;
} else {
iremovePrefix(&mcf->endpoint, "http://");
}
Expand Down Expand Up @@ -702,6 +711,36 @@ char* addResourceAttr(ngx_conf_t* cf, ngx_command_t* cmd, void* conf)
return NGX_CONF_OK;
}

char* setTrustedCertificate(ngx_conf_t* cf, ngx_command_t* cmd, void* conf) {
auto path = ((ngx_str_t*)cf->args->elts)[1];
auto mcf = getMainConf(cf);

if (ngx_get_full_name(cf->pool, &cf->cycle->conf_prefix, &path) != NGX_OK) {
return (char*)NGX_CONF_ERROR;
}

try {
std::ifstream file{(const char*)path.data, std::ios::binary};
if (!file.is_open()) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno,
"failed to open \"%V\"", &path);
return (char*)NGX_CONF_ERROR;
}
file.exceptions(std::ios::failbit | std::ios::badbit);
file.seekg(0, std::ios::end);
size_t size = file.tellg();
mcf->trustedCert.resize(size);
file.seekg(0);
file.read(&mcf->trustedCert[0], mcf->trustedCert.size());
} catch (const std::exception& e) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"failed to read \"%V\": %s", &path, e.what());
return (char*)NGX_CONF_ERROR;
}

return NGX_CONF_OK;
}

void* createMainConf(ngx_conf_t* cf)
{
auto cln = ngx_pool_cleanup_add(cf->pool, sizeof(MainConf));
Expand Down
14 changes: 11 additions & 3 deletions src/trace_service_client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,18 @@ class TraceServiceClient {
typedef std::function<void (Request, Response, grpc::Status)>
ResponseCb;

TraceServiceClient(const std::string& target)
TraceServiceClient(const std::string& target, bool ssl,
const std::string& trustedCert)
{
auto channel = grpc::CreateChannel(
target, grpc::InsecureChannelCredentials());
std::shared_ptr<grpc::ChannelCredentials> creds;
if (ssl) {
grpc::SslCredentialsOptions options;
options.pem_root_certs = trustedCert;
creds = grpc::SslCredentials(options);
} else {
creds = grpc::InsecureChannelCredentials();
}
auto channel = grpc::CreateChannel(target, creds);
channel->GetState(true); // trigger 'connecting' state

stub = TraceService::NewStub(channel);
Expand Down

0 comments on commit 6c1659a

Please sign in to comment.