Skip to content

Commit

Permalink
feat: add a SSL verify mode option for the OTLP exporter (#768)
Browse files Browse the repository at this point in the history
* feat: add a verify mode option for the OTLP exporter

This change covers adding configuration to the OTLP Exporter
to support exporting to Collectors that have certificates that can't be
 verified by OpenSSL.

This approach is copied from the similar change for the Jaeger
CollectorExporter:
open-telemetry/opentelemetry-ruby#743

* add documentation on OTLP exporter configuration

* Fix typo in README

Co-authored-by: Ariel Valentin <[email protected]>

Co-authored-by: Ariel Valentin <[email protected]>
Co-authored-by: Francis Bogsanyi <[email protected]>
  • Loading branch information
3 people authored May 25, 2021
1 parent a044609 commit 86c5d03
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 1 deletion.
16 changes: 16 additions & 0 deletions exporter/otlp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,22 @@ end

For additional examples, see the [examples on github][examples-github].

## How can I configure the OTLP exporter?

The collector exporter can be configured explicitly in code, as shown above, or via environment variables. The configuration parameters, environment variables, and defaults are shown below.

| Parameter | Environment variable | Default |
| ------------------- | -------------------------------------------- | ----------------------------------- |
| `endpoint:` | `OTEL_EXPORTER_OTLP_ENDPOINT` | `"http://localhost:4317/v1/traces"` |
| `certificate_file: `| `OTEL_EXPORTER_OTLP_CERTIFICATE` | |
| `headers:` | `OTEL_EXPORTER_OTLP_HEADERS` | |
| `compression:` | `OTEL_EXPORTER_OTLP_COMPRESSION` | |
| `timeout:` | `OTEL_EXPORTER_OTLP_TIMEOUT` | `10` |
| `ssl_verify_mode:` | `OTEL_RUBY_EXPORTER_OTLP_SSL_VERIFY_PEER` or | `OpenSSL::SSL:VERIFY_PEER` |
| | `OTEL_RUBY_EXPORTER_OTLP_SSL_VERIFY_NONE` | |

`ssl_verify_mode:` parameter values should be flags for server certificate verification: `OpenSSL::SSL:VERIFY_PEER` and `OpenSSL::SSL:VERIFY_NONE` are acceptable. These values can also be set using the appropriately named environment variables as shown where `VERIFY_PEER` will take precedence over `VERIFY_NONE`. Please see [the Net::HTTP docs](https://ruby-doc.org/stdlib-2.5.1/libdoc/net/http/rdoc/Net/HTTP.html#verify_mode) for more information about these flags.

## How can I get involved?

The `opentelemetry-exporter-otlp` gem source is [on github][repo-github], along with related gems including `opentelemetry-sdk`.
Expand Down
14 changes: 13 additions & 1 deletion exporter/otlp/lib/opentelemetry/exporter/otlp/exporter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,19 @@ class Exporter # rubocop:disable Metrics/ClassLength
WRITE_TIMEOUT_SUPPORTED = Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.6')
private_constant(:KEEP_ALIVE_TIMEOUT, :RETRY_COUNT, :WRITE_TIMEOUT_SUPPORTED)

def initialize(endpoint: config_opt('OTEL_EXPORTER_OTLP_TRACES_ENDPOINT', 'OTEL_EXPORTER_OTLP_ENDPOINT', default: 'https://localhost:4317/v1/traces'), # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
def self.ssl_verify_mode
if ENV.key?('OTEL_RUBY_EXPORTER_OTLP_SSL_VERIFY_PEER')
OpenSSL::SSL::VERIFY_PEER
elsif ENV.key?('OTEL_RUBY_EXPORTER_OTLP_SSL_VERIFY_NONE')
OpenSSL::SSL::VERIFY_NONE
else
OpenSSL::SSL::VERIFY_PEER
end
end

def initialize(endpoint: config_opt('OTEL_EXPORTER_OTLP_TRACES_ENDPOINT', 'OTEL_EXPORTER_OTLP_ENDPOINT', default: 'https://localhost:4317/v1/traces'), # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Metrics/MethodLength
certificate_file: config_opt('OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE', 'OTEL_EXPORTER_OTLP_CERTIFICATE'),
ssl_verify_mode: Exporter.ssl_verify_mode,
headers: config_opt('OTEL_EXPORTER_OTLP_TRACES_HEADERS', 'OTEL_EXPORTER_OTLP_HEADERS'),
compression: config_opt('OTEL_EXPORTER_OTLP_TRACES_COMPRESSION', 'OTEL_EXPORTER_OTLP_COMPRESSION'),
timeout: config_opt('OTEL_EXPORTER_OTLP_TRACES_TIMEOUT', 'OTEL_EXPORTER_OTLP_TIMEOUT', default: 10),
Expand All @@ -49,6 +60,7 @@ def initialize(endpoint: config_opt('OTEL_EXPORTER_OTLP_TRACES_ENDPOINT', 'OTEL_

@http = Net::HTTP.new(@uri.host, @uri.port)
@http.use_ssl = @uri.scheme == 'https'
@http.verify_mode = ssl_verify_mode
@http.ca_file = certificate_file unless certificate_file.nil?
@http.keep_alive_timeout = KEEP_ALIVE_TIMEOUT

Expand Down
33 changes: 33 additions & 0 deletions exporter/otlp/test/opentelemetry/exporter/otlp/exporter_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
_(http.ca_file).must_be_nil
_(http.use_ssl?).must_equal true
_(http.address).must_equal 'localhost'
_(http.verify_mode).must_equal OpenSSL::SSL::VERIFY_PEER
_(http.port).must_equal 4317
end

Expand Down Expand Up @@ -57,6 +58,7 @@
'OTEL_EXPORTER_OTLP_CERTIFICATE' => '/foo/bar',
'OTEL_EXPORTER_OTLP_HEADERS' => 'a=b,c=d',
'OTEL_EXPORTER_OTLP_COMPRESSION' => 'gzip',
'OTEL_RUBY_EXPORTER_OTLP_SSL_VERIFY_NONE' => 'true',
'OTEL_EXPORTER_OTLP_TIMEOUT' => '11') do
OpenTelemetry::Exporter::OTLP::Exporter.new
end
Expand All @@ -68,6 +70,7 @@
_(http.ca_file).must_equal '/foo/bar'
_(http.use_ssl?).must_equal false
_(http.address).must_equal 'localhost'
_(http.verify_mode).must_equal OpenSSL::SSL::VERIFY_NONE
_(http.port).must_equal 1234
end

Expand All @@ -76,11 +79,13 @@
'OTEL_EXPORTER_OTLP_CERTIFICATE' => '/foo/bar',
'OTEL_EXPORTER_OTLP_HEADERS' => 'a:b,c:d',
'OTEL_EXPORTER_OTLP_COMPRESSION' => 'flate',
'OTEL_RUBY_EXPORTER_OTLP_SSL_VERIFY_PEER' => 'true',
'OTEL_EXPORTER_OTLP_TIMEOUT' => '11') do
OpenTelemetry::Exporter::OTLP::Exporter.new(endpoint: 'http://localhost:4321',
certificate_file: '/baz',
headers: { 'x' => 'y' },
compression: 'gzip',
ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE,
timeout: 12)
end
_(exp.instance_variable_get(:@headers)).must_equal('x' => 'y')
Expand All @@ -90,11 +95,39 @@
http = exp.instance_variable_get(:@http)
_(http.ca_file).must_equal '/baz'
_(http.use_ssl?).must_equal false
_(http.verify_mode).must_equal OpenSSL::SSL::VERIFY_NONE
_(http.address).must_equal 'localhost'
_(http.port).must_equal 4321
end
end

describe 'ssl_verify_mode:' do
it 'can be set to VERIFY_NONE by an envvar' do
exp = with_env('OTEL_RUBY_EXPORTER_OTLP_SSL_VERIFY_NONE' => 'true') do
OpenTelemetry::Exporter::OTLP::Exporter.new
end
http = exp.instance_variable_get(:@http)
_(http.verify_mode).must_equal OpenSSL::SSL::VERIFY_NONE
end

it 'can be set to VERIFY_PEER by an envvar' do
exp = with_env('OTEL_RUBY_EXPORTER_OTLP_SSL_VERIFY_PEER' => 'true') do
OpenTelemetry::Exporter::OTLP::Exporter.new
end
http = exp.instance_variable_get(:@http)
_(http.verify_mode).must_equal OpenSSL::SSL::VERIFY_PEER
end

it 'VERIFY_PEER will override VERIFY_NONE' do
exp = with_env('OTEL_RUBY_EXPORTER_OTLP_SSL_VERIFY_NONE' => 'true',
'OTEL_RUBY_EXPORTER_OTLP_SSL_VERIFY_PEER' => 'true') do
OpenTelemetry::Exporter::OTLP::Exporter.new
end
http = exp.instance_variable_get(:@http)
_(http.verify_mode).must_equal OpenSSL::SSL::VERIFY_PEER
end
end

describe '#export' do
let(:exporter) { OpenTelemetry::Exporter::OTLP::Exporter.new }

Expand Down

0 comments on commit 86c5d03

Please sign in to comment.