Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(trace-otlp-grpc): configure security with env vars #2827

Merged
merged 56 commits into from
May 17, 2022
Merged
Show file tree
Hide file tree
Changes from 53 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
a614e9e
feat(trace-otlp-grpc): add insecure configs
svetlanabrennan Mar 1, 2022
5de22f2
feat(trace-otlp-grpc): add unit tests
svetlanabrennan Mar 1, 2022
abb85b7
feat(trace-otlp-grpc): wip add certificate and tests
svetlanabrennan Mar 4, 2022
25ff0a7
feat(trace-otlp-grpc): fix security config and unit tests
svetlanabrennan Mar 9, 2022
ff0c262
feat(trace-otlp-grpc): add env and certificate tests
svetlanabrennan Mar 9, 2022
10ac242
feat(trace-otlp-grpc): wip certificate tests
svetlanabrennan Mar 10, 2022
b8f6b79
feat(trace-otlp-grpc): fix lint error
svetlanabrennan Mar 10, 2022
ec98d2e
Merge branch 'main' into add-insecure-config
svetlanabrennan Mar 10, 2022
5d1cc75
Merge branch 'main' into add-insecure-config
svetlanabrennan Mar 16, 2022
703ff36
feat(trace-otlp-grpc): merge main to add-insecure-config
svetlanabrennan Mar 28, 2022
3c124fe
Merge branch 'main' into add-insecure-config
svetlanabrennan Apr 5, 2022
fd39a9a
feat(trace-otlp-grpc): wip add additional security setting checks
svetlanabrennan Apr 5, 2022
cee07d3
feat(trace-otlp-grpc): update default url to http scheme
svetlanabrennan Apr 5, 2022
1eba925
feat(trace-otlp-grpc): wip add tests
svetlanabrennan Apr 6, 2022
66c9471
feat(trace-otlp-grpc): wip refactor function around insecure setting
svetlanabrennan Apr 6, 2022
dcba873
Merge branch 'main' into add-insecure-config
svetlanabrennan Apr 6, 2022
87ca75c
feat(trace-otlp-grpc): wip update returned security setting for some …
svetlanabrennan Apr 7, 2022
1fb546e
Merge branch 'add-insecure-config' of github.com:svetlanabrennan/open…
svetlanabrennan Apr 7, 2022
27b601f
feat(trace-otlp-grpc): update certificate and add tests
svetlanabrennan Apr 11, 2022
e4128c4
Merge branch 'main' into add-insecure-config
svetlanabrennan Apr 18, 2022
b977006
feat(trace-otlp-grpc): wip certificate tests
svetlanabrennan Apr 18, 2022
11efece
feat(trace-otlp-grpc): fix tests
svetlanabrennan Apr 19, 2022
e4bccd1
feat(trace-otlp-grpc): add diag tests
svetlanabrennan Apr 19, 2022
93e2b5a
feat(trace-otlp-grpc): update default url
svetlanabrennan Apr 19, 2022
9eb7b09
feat(trace-otlp-grpc): fix tests
svetlanabrennan Apr 19, 2022
bbb3643
feat(trace-otlp-grpc): fix tests
svetlanabrennan Apr 19, 2022
c954b8a
Merge branch 'main' into add-insecure-config
svetlanabrennan Apr 20, 2022
72ff643
feat(trace-otlp-grpc): add changelog item
svetlanabrennan Apr 20, 2022
ebec97c
feat(trace-otlp-grpc): add grpc scheme check and update test
svetlanabrennan Apr 20, 2022
5f5de7c
feat(trace-otlp-grpc): add grpc scheme test
svetlanabrennan Apr 20, 2022
cf08aea
feat(trace-otlp-grpc): fix metrics default url
svetlanabrennan Apr 20, 2022
30196c1
feat(trace-otlp-grpc): merge main into add-secure-config
svetlanabrennan Apr 20, 2022
02e5b98
feat(trace-otlp-grpc): update readme
svetlanabrennan Apr 20, 2022
1e19f03
feat(trace-otlp-grpc): fix lint
svetlanabrennan Apr 20, 2022
ba28072
Merge branch 'main' into add-insecure-config
svetlanabrennan Apr 20, 2022
bb8dfaa
feat(trace-otlp-grpc): fix changelog and get security from env func
svetlanabrennan Apr 21, 2022
ba6b11f
Merge branch 'main' into add-insecure-config
svetlanabrennan Apr 21, 2022
16c62b7
feat(trace-otlp-grpc): wip troubleshoot
svetlanabrennan Apr 21, 2022
899d478
feat(trace-otlp-grpc): fix readme
svetlanabrennan Apr 21, 2022
6126f5d
Merge branch 'main' into add-insecure-config
svetlanabrennan Apr 25, 2022
941937d
Merge branch 'main' into add-insecure-config
svetlanabrennan Apr 26, 2022
5b3b351
feat(trace-otlp-grpc): refactor code and fix lint
svetlanabrennan Apr 26, 2022
748db96
feat(trace-otlp-grpc): remove grpc scheme and grpc scheme tests
svetlanabrennan Apr 27, 2022
79e0ae4
Merge branch 'main' into add-insecure-config
svetlanabrennan Apr 28, 2022
30bdd55
Merge branch 'main' into add-insecure-config
svetlanabrennan May 2, 2022
b99dfa2
Merge branch 'main' into add-insecure-config
svetlanabrennan May 5, 2022
4f275e7
Merge branch 'main' into add-insecure-config
svetlanabrennan May 9, 2022
0828912
Merge branch 'main' into add-insecure-config
svetlanabrennan May 10, 2022
2182c5e
Merge branch 'main' into add-insecure-config
dyladan May 11, 2022
ab12999
Merge branch 'main' into add-insecure-config
svetlanabrennan May 11, 2022
9289b9e
Merge branch 'main' into add-insecure-config
svetlanabrennan May 12, 2022
2156472
feat(trace-otlp-grpc): fix credentials for failing test afer main merge
svetlanabrennan May 12, 2022
39e3126
Merge branch 'main' into add-insecure-config
svetlanabrennan May 12, 2022
4ae7510
feat(trace-otlp-grpc): move changelog to unreleased section
svetlanabrennan May 16, 2022
531f19a
Use exact match for protocol check to avoid leaking cases like httpx
svetlanabrennan May 16, 2022
11df1a1
Merge branch 'main' into add-insecure-config
svetlanabrennan May 16, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions experimental/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ All notable changes to experimental packages in this project will be documented
* feat(instrumentation-xhr): add applyCustomAttributesOnSpan hook #2134 @mhennoch
* feat(proto): add @opentelemetry/otlp-transformer package with hand-rolled transformation #2746 @dyladan
* feat(sdk-metrics-base): shutdown and forceflush on MeterProvider #2890 @legendecas
* feat(trace-otlp-grpc): configure security with env vars #2827 @svetlanabrennan
svetlanabrennan marked this conversation as resolved.
Show resolved Hide resolved
svetlanabrennan marked this conversation as resolved.
Show resolved Hide resolved
* feat(sdk-metrics-base): return the same meter for identical input to getMeter #2901 @legendecas
* feat(otlp-exporter): add [OTEL_EXPORTER_OTLP_TIMEOUT](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#configuration-options) env var to otlp exporters #2738 @svetlanabrennan
* feat(sdk-metrics-base): hoist async instrument callback invocations #2822 @legendecas
Expand Down
31 changes: 20 additions & 11 deletions experimental/packages/exporter-trace-otlp-grpc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ const { BasicTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc');

const collectorOptions = {
// url is optional and can be omitted - default is localhost:4317
url: '<collector-hostname>:<port>',
// url is optional and can be omitted - default is http://localhost:4317
url: 'http://<collector-hostname>:<port>',
};

const provider = new BasicTracerProvider();
Expand All @@ -51,8 +51,8 @@ const { BasicTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc');

const collectorOptions = {
// url is optional and can be omitted - default is localhost:4317
url: '<collector-hostname>:<port>',
// url is optional and can be omitted - default is http://localhost:4317
url: 'http://<collector-hostname>:<port>',
credentials: grpc.credentials.createSsl(),
};

Expand Down Expand Up @@ -91,8 +91,8 @@ const metadata = new grpc.Metadata();
metadata.set('k', 'v');

const collectorOptions = {
// url is optional and can be omitted - default is localhost:4317
url: '<collector-hostname>:<port>',
// url is optional and can be omitted - default is http://localhost:4317
url: 'http://<collector-hostname>:<port>',
metadata, // // an optional grpc.Metadata object to be sent with each request
};

Expand Down Expand Up @@ -135,8 +135,8 @@ By default no compression will be used. To use compression, set it programmatica
const { CompressionAlgorithm } = require('@opentelemetry/exporter-trace-otlp-grpc');

const collectorOptions = {
// url is optional and can be omitted - default is localhost:4317
url: '<collector-hostname>:<port>',
// url is optional and can be omitted - default is http://localhost:4317
url: 'http://<collector-hostname>:<port>',
metadata, // // an optional grpc.Metadata object to be sent with each request
compression: CompressionAlgorithm.GZIP,
};
Expand All @@ -149,11 +149,20 @@ const exporter = new OTLPTraceExporter(collectorOptions);

| Environment variable | Description |
|----------------------|-------------|
| OTEL_EXPORTER_OTLP_TRACES_TIMEOUT | The maximum waiting time, in milliseconds, allowed to send each OTLP trace batch. Default is 10000. |
| OTEL_EXPORTER_OTLP_TIMEOUT | The maximum waiting time, in milliseconds, allowed to send each OTLP trace and metric batch. Default is 10000. |
| OTEL_EXPORTER_OTLP_TRACES_COMPRESSION | The compression type to use on OTLP trace requests. Options include gzip. By default no compression will be used. |
| OTEL_EXPORTER_OTLP_COMPRESSION | The compression type to use on OTLP trace, metric, and log requests. Options include gzip. By default no compression will be used. |
> The per-signal environment variables (`OTEL_EXPORTER_OTLP_TRACES_TIMEOUT`) takes precedence and non-per-signal environment variable (`OTEL_EXPORTER_OTLP_TIMEOUT`).
| OTEL_EXPORTER_OTLP_TRACES_INSECURE | Whether to enable client transport security for the exporter's gRPC connection for trace requests. This option only applies to OTLP/gRPC when an endpoint is provided without the http or https scheme. Options include true or false. By default insecure is false which creates a secure connection. |
| OTEL_EXPORTER_OTLP_INSECURE | Whether to enable client transport security for the exporter's gRPC connection for trace, metric and log requests. This option only applies to OTLP/gRPC when an endpoint is provided without the http or https scheme. Options include true or false. By default insecure is false which creates a secure connection. |
| OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE | The path to the file containing trusted root certificate to use when verifying an OTLP trace server's TLS credentials. By default the host platform's trusted root certificate is used.|
| OTEL_EXPORTER_OTLP_CERTIFICATE | The path to the file containing trusted root certificate to use when verifying an OTLP trace, metric, or log server's TLS credentials. By default the host platform's trusted root certificate is used. |
| OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY | The path to the file containing private client key to use when verifying an OTLP trace client's TLS credentials. Must provide a client certificate/chain when providing a private client key. By default no client key file is used. |
| OTEL_EXPORTER_OTLP_CLIENT_KEY | The path to the file containing private client key to use when verifying an OTLP trace, metric or log client's TLS credentials. Must provide a client certificate/chain when providing a private client key. By default no client key file is used. |
| OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE | The path to the file containing trusted client certificate/chain for clients private key to use when verifying an OTLP trace server's TLS credentials. Must provide a private client key when providing a certificate/chain. By default no chain file is used. |
| OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE | The path to the file containing trusted client certificate/chain for clients private key to use when verifying an OTLP trace, metric and log server's TLS credentials. Must provide a private client key when providing a certificate/chain. By default no chain file is used. |
| OTEL_EXPORTER_OTLP_TRACES_TIMEOUT | The maximum waiting time, in milliseconds, allowed to send each OTLP trace batch. Default is 10000. |
| OTEL_EXPORTER_OTLP_TIMEOUT | The maximum waiting time, in milliseconds, allowed to send each OTLP trace and metric batch. Default is 10000. |

> Settings configured programmatically take precedence over environment variables. Per-signal environment variables take precedence over non-per-signal environment variables.

## Running opentelemetry-collector locally to see the traces

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,11 @@ import {
OTLPGRPCExporterConfigNode,
OTLPGRPCExporterNodeBase,
ServiceClientType,
validateAndNormalizeUrl
validateAndNormalizeUrl,
DEFAULT_COLLECTOR_URL
} from '@opentelemetry/otlp-grpc-exporter-base';
import { createExportTraceServiceRequest, IExportTraceServiceRequest } from '@opentelemetry/otlp-transformer';

const DEFAULT_COLLECTOR_URL = 'localhost:4317';

/**
* OTLP Trace Exporter for Node
*/
Expand Down Expand Up @@ -55,7 +54,7 @@ export class OTLPTraceExporter
? validateAndNormalizeUrl(getEnv().OTEL_EXPORTER_OTLP_TRACES_ENDPOINT)
: getEnv().OTEL_EXPORTER_OTLP_ENDPOINT.length > 0
? validateAndNormalizeUrl(getEnv().OTEL_EXPORTER_OTLP_ENDPOINT)
: DEFAULT_COLLECTOR_URL;
: validateAndNormalizeUrl(DEFAULT_COLLECTOR_URL);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to validate a hardcoded default URL?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes because the DEFAULT_COLLECTOR_URL didn't have a scheme so we didn't need to pass it to validateAndNormalizeUrl like we do when user adds a url to config.url or when using env vars.

Now that I updated DEFAULT_COLLECTOR_URL to have an http scheme (like we discussed in the sig so it matches the spec) so we need to pass it to validateAndNormalizeUrl to remove the scheme.

}

getServiceClientType() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,9 @@ const testCollectorExporter = (params: TestParams) =>
fs.readFileSync('./test/certs/client.key'),
fs.readFileSync('./test/certs/client.crt')
)
: undefined;
: grpc.credentials.createInsecure();
collectorExporter = new OTLPTraceExporter({
url: 'grpcs://' + address,
url: 'https://' + address,
credentials,
metadata: params.metadata,
});
Expand Down Expand Up @@ -207,7 +207,7 @@ const testCollectorExporter = (params: TestParams) =>
fs.readFileSync('./test/certs/client.key'),
fs.readFileSync('./test/certs/client.crt')
)
: undefined;
: grpc.credentials.createInsecure();

const collectorExporterWithTimeout = new OTLPTraceExporter({
url: 'grpcs://' + address,
Expand Down Expand Up @@ -236,9 +236,9 @@ const testCollectorExporter = (params: TestParams) =>
fs.readFileSync('./test/certs/client.key'),
fs.readFileSync('./test/certs/client.crt')
)
: undefined;
: grpc.credentials.createInsecure();
collectorExporter = new OTLPTraceExporter({
url: 'grpcs://' + address,
url: 'https://' + address,
credentials,
metadata: params.metadata,
compression: CompressionAlgorithm.GZIP,
Expand Down Expand Up @@ -286,11 +286,11 @@ const testCollectorExporter = (params: TestParams) =>
fs.readFileSync('./test/certs/client.key'),
fs.readFileSync('./test/certs/client.crt')
)
: undefined;
: grpc.credentials.createInsecure();

envSource.OTEL_EXPORTER_OTLP_COMPRESSION = 'gzip';
collectorExporter = new OTLPTraceExporter({
url: 'grpcs://' + address,
url: 'https://' + address,
credentials,
metadata: params.metadata,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ The OTLPMetricsExporter in Node expects the URL to only be the hostname. It will
const { MeterProvider, PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics-base');
const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-grpc');
const collectorOptions = {
// url is optional and can be omitted - default is grpc://localhost:4317
url: 'grpc://<collector-hostname>:<port>',
// url is optional and can be omitted - default is http://localhost:4317
url: 'http://<collector-hostname>:<port>',
};

const exporter = new OTLPMetricExporter(collectorOptions);
Expand All @@ -48,6 +48,23 @@ const counter = meter.createCounter('metric_name');
counter.add(10, { 'key': 'value' });
```

## Environment Variable Configuration

| Environment variable | Description |
|----------------------|-------------|
| OTEL_EXPORTER_OTLP_METRICS_COMPRESSION | The compression type to use on OTLP metric requests. Options include gzip. By default no compression will be used. |
| OTEL_EXPORTER_OTLP_COMPRESSION | The compression type to use on OTLP trace, metric, and log requests. Options include gzip. By default no compression will be used. |
| OTEL_EXPORTER_OTLP_METRICS_INSECURE | Whether to enable client transport security for the exporter's gRPC connection for metric requests. This option only applies to OTLP/gRPC when an endpoint is provided without the http or https scheme. Options include true or false. By default insecure is false which creates a secure connection. |
| OTEL_EXPORTER_OTLP_INSECURE | Whether to enable client transport security for the exporter's gRPC connection for trace, metric and log requests. This option only applies to OTLP/gRPC when an endpoint is provided without the http or https scheme. Options include true or false. By default insecure is false which creates a secure connection. |
| OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE | The path to the file containing trusted root certificate to use when verifying an OTLP metric server's TLS credentials. By default the host platform's trusted root certificate is used.|
| OTEL_EXPORTER_OTLP_CERTIFICATE | The path to the file containing trusted root certificate to use when verifying an OTLP trace, metric, or log server's TLS credentials. By default the host platform's trusted root certificate is used. |
| OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY | The path to the file containing private client key to use when verifying an OTLP metric client's TLS credentials. Must provide a client certificate/chain when providing a private client key. By default no client key file is used. |
| OTEL_EXPORTER_OTLP_CLIENT_KEY | The path to the file containing private client key to use when verifying an OTLP trace, metric or log client's TLS credentials. Must provide a client certificate/chain when providing a private client key. By default no client key file is used. |
| OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE | The path to the file containing trusted client certificate/chain for clients private key to use when verifying an OTLP metric server's TLS credentials. Must provide a private client key when providing a certificate/chain. By default no chain file is used. |
| OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE | The path to the file containing trusted client certificate/chain for clients private key to use when verifying an OTLP trace, metric and log server's TLS credentials. Must provide a private client key when providing a certificate/chain. By default no chain file is used. |

> Settings configured programmatically take precedence over environment variables. Per-signal environment variables take precedence over non-per-signal environment variables.

## Running opentelemetry-collector locally to see the metrics

1. Go to `examples/otlp-exporter-node`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,13 @@ import {
OTLPGRPCExporterConfigNode,
OTLPGRPCExporterNodeBase,
ServiceClientType,
validateAndNormalizeUrl
validateAndNormalizeUrl,
DEFAULT_COLLECTOR_URL
} from '@opentelemetry/otlp-grpc-exporter-base';
import { baggageUtils, getEnv } from '@opentelemetry/core';
import { Metadata } from '@grpc/grpc-js';
import { createExportMetricsServiceRequest, IExportMetricsServiceRequest } from '@opentelemetry/otlp-transformer';

const DEFAULT_COLLECTOR_URL = 'localhost:4317';


class OTLPMetricExporterProxy extends OTLPGRPCExporterNodeBase<ResourceMetrics, IExportMetricsServiceRequest> {

constructor(config: OTLPGRPCExporterConfigNode & OTLPMetricExporterOptions= defaultOptions) {
Expand All @@ -59,7 +57,7 @@ class OTLPMetricExporterProxy extends OTLPGRPCExporterNodeBase<ResourceMetrics,
? validateAndNormalizeUrl(getEnv().OTEL_EXPORTER_OTLP_METRICS_ENDPOINT)
: getEnv().OTEL_EXPORTER_OTLP_ENDPOINT.length > 0
? validateAndNormalizeUrl(getEnv().OTEL_EXPORTER_OTLP_ENDPOINT)
: DEFAULT_COLLECTOR_URL;
: validateAndNormalizeUrl(DEFAULT_COLLECTOR_URL);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same answer as this one

}

convert(metrics: ResourceMetrics[]): IExportMetricsServiceRequest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,9 @@ const testOTLPMetricExporter = (params: TestParams) =>
fs.readFileSync('./test/certs/client.key'),
fs.readFileSync('./test/certs/client.crt')
)
: undefined;
: grpc.credentials.createInsecure();
collectorExporter = new OTLPMetricExporter({
url: 'grpcs://' + address,
url: 'https://' + address,
credentials,
metadata: params.metadata,
temporalityPreference: AggregationTemporality.CUMULATIVE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@

export * from './OTLPGRPCExporterNodeBase';
export { ServiceClientType, OTLPGRPCExporterConfigNode } from './types';
export { validateAndNormalizeUrl, GrpcCompressionAlgorithm } from './util';
export { DEFAULT_COLLECTOR_URL, validateAndNormalizeUrl, GrpcCompressionAlgorithm } from './util';
104 changes: 100 additions & 4 deletions experimental/packages/otlp-grpc-exporter-base/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,19 @@ import { getEnv, globalErrorHandler } from '@opentelemetry/core';
import * as path from 'path';
import { OTLPGRPCExporterNodeBase } from './OTLPGRPCExporterNodeBase';
import { URL } from 'url';
import * as fs from 'fs';
import { GRPCQueueItem, OTLPGRPCExporterConfigNode, ServiceClientType, } from './types';
import { CompressionAlgorithm, ExportServiceError, OTLPExporterError } from '@opentelemetry/otlp-exporter-base';

export const DEFAULT_COLLECTOR_URL = 'http://localhost:4317';

export function onInit<ExportItem, ServiceRequest>(
collector: OTLPGRPCExporterNodeBase<ExportItem, ServiceRequest>,
config: OTLPGRPCExporterConfigNode
): void {
collector.grpcQueue = [];
const credentials: grpc.ChannelCredentials =
config.credentials || grpc.credentials.createInsecure();

const credentials: grpc.ChannelCredentials = configureSecurity(config.credentials, collector.url);

const includeDirs = [path.resolve(__dirname, '..', 'protos')];

Expand Down Expand Up @@ -120,14 +123,107 @@ export function validateAndNormalizeUrl(url: string): string {
'URL path should not be set when using grpc, the path part of the URL will be ignored.'
);
}
if (target.protocol !== '' && !target.protocol?.match(/(http|grpc)s?/)) {
if (target.protocol !== '' && !target.protocol?.match(/(http)s?/)) {
svetlanabrennan marked this conversation as resolved.
Show resolved Hide resolved
diag.warn(
'URL protocol should be http(s):// or grpc(s)://. Using grpc://.'
'URL protocol should be http(s)://. Using http://.'
);
}
return target.host;
}

export function configureSecurity(credentials: grpc.ChannelCredentials | undefined, endpoint: string):
grpc.ChannelCredentials {

let insecure: boolean;

if (credentials) {
return credentials;
} else if (endpoint.startsWith('https://')) {
insecure = false;
} else if (endpoint.startsWith('http://') || endpoint === DEFAULT_COLLECTOR_URL) {
insecure = true;
} else {
insecure = getSecurityFromEnv();
}

if (insecure) {
return grpc.credentials.createInsecure();
} else {
return useSecureConnection();
}
}

function getSecurityFromEnv(): boolean {
const definedInsecure =
getEnv().OTEL_EXPORTER_OTLP_TRACES_INSECURE ||
getEnv().OTEL_EXPORTER_OTLP_INSECURE;

if (definedInsecure) {
return definedInsecure.toLowerCase() === 'true';
} else {
return false;
}
}

export function useSecureConnection(): grpc.ChannelCredentials {
const rootCertPath = retrieveRootCert();
const privateKeyPath = retrievePrivateKey();
const certChainPath = retrieveCertChain();

return grpc.credentials.createSsl(rootCertPath, privateKeyPath, certChainPath);
}

function retrieveRootCert(): Buffer | undefined {
const rootCertificate =
getEnv().OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE ||
getEnv().OTEL_EXPORTER_OTLP_CERTIFICATE;

if (rootCertificate) {
try {
return fs.readFileSync(path.resolve(process.cwd(), rootCertificate));
} catch {
diag.warn('Failed to read root certificate file');
return undefined;
}
} else {
return undefined;
}
}

function retrievePrivateKey(): Buffer | undefined {
const clientKey =
getEnv().OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY ||
getEnv().OTEL_EXPORTER_OTLP_CLIENT_KEY;

if (clientKey) {
try {
return fs.readFileSync(path.resolve(process.cwd(), clientKey));
} catch {
diag.warn('Failed to read client certificate private key file');
return undefined;
}
} else {
return undefined;
}
}

function retrieveCertChain(): Buffer | undefined {
const clientChain =
getEnv().OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE ||
getEnv().OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE;

if (clientChain) {
try {
return fs.readFileSync(path.resolve(process.cwd(), clientChain));
} catch {
diag.warn('Failed to read client certificate chain file');
return undefined;
}
} else {
return undefined;
}
}

function toGrpcCompression(compression: CompressionAlgorithm): GrpcCompressionAlgorithm {
if(compression === CompressionAlgorithm.NONE)
return GrpcCompressionAlgorithm.NONE;
Expand Down
Loading