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

[exporter/signalfxexporter] allow user to add their own CA to the cert pool #16250

Merged
merged 3 commits into from
Nov 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 19 additions & 0 deletions .chloggen/signalfx-exporter.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
component: exporter/signalfxexporter

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Allow user to add a custom CA so the ingest and api clients can verify and communicate with custom TLS servers.

# One or more tracking issues related to the change
issues: [16250]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext: |
"`ingest_tls`" and "`api_tls`" can be used to set the absolute path to the CA file "`ca_file`".
This is needed when the exporter is pointing to a TLS enabled signalfx receiver or/and TLS enabled http_forwarder
and the CA is not in the system cert pool
18 changes: 18 additions & 0 deletions exporter/signalfxexporter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,24 @@ that are allowed to be used as a dimension key in addition to alphanumeric
characters. Each nonalphanumeric dimension key character that isn't in this string
will be replaced with a `_`.
- `max_connections` (default = 100): The maximum number of idle HTTP connection the exporter can keep open.
- `ingest_tls`: (no default) exposes a list of TLS settings to establish a secure connection with signafx receiver configured on another collector instance.
- `ca_file` needs to be set if the exporter's `ingest_url` is pointing to a signalfx receiver
with TLS enabled and using a self-signed certificate where its CA is not loaded in the system cert pool.
Full list of TLS options can be found in the configtls [README](https://github.com/open-telemetry/opentelemetry-collector/tree/main/config/configtls#client-configuration)
The following example instructs the signalfx exporter ingest client to use a custom `ca_file` to verify the server certificate.
```yaml
ingest_tls:
ca_file: "/etc/opt/certs/ca.pem"
```
- `api_tls`: (no default) exposes a list of TLS settings to establish a secure connection with http_forwarder extension configured on another collector instance.
- `ca_file` needs to be set if the exporter's `api_url` is pointing to a http_forwarder extension
with TLS enabled and using a self-signed certificate where its CA is not loaded in the system cert pool.
Full list of TLS options can be found in the configtls [README](https://github.com/open-telemetry/opentelemetry-collector/tree/main/config/configtls#client-configuration)
The following example instructs the signalfx exporter api client to use a custom `ca_file` to verify the server certificate.
```yaml
api_tls:
ca_file: "/etc/opt/certs/ca.pem"
```

In addition, this exporter offers queued retry which is enabled by default.
Information about queued retry configuration parameters can be found
Expand Down
25 changes: 18 additions & 7 deletions exporter/signalfxexporter/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"time"

"go.opentelemetry.io/collector/config"
"go.opentelemetry.io/collector/config/configtls"
"go.opentelemetry.io/collector/confmap"
"go.opentelemetry.io/collector/exporter/exporterhelper"

Expand Down Expand Up @@ -55,10 +56,18 @@ type Config struct {
// path: "/v2/datapoint" for metrics, and "/v2/event" for events.
IngestURL string `mapstructure:"ingest_url"`

// ingest_tls needs to be set if the exporter's IngestURL is pointing to a signalfx receiver
// with TLS enabled and using a self-signed certificate where its CA is not loaded in the system cert pool.
IngestTLSSettings configtls.TLSClientSetting `mapstructure:"ingest_tls,omitempty"`

// APIURL is the destination to where SignalFx metadata will be sent. This
// value takes precedence over the value of Realm
APIURL string `mapstructure:"api_url"`

// api_tls needs to be set if the exporter's APIURL is pointing to a httforwarder extension
// with TLS enabled and using a self-signed certificate where its CA is not loaded in the system cert pool.
APITLSSettings configtls.TLSClientSetting `mapstructure:"api_tls,omitempty"`

// Headers are a set of headers to be added to the HTTP request sending
// trace data. These can override pre-defined header values used by the
// exporter, eg: "User-Agent" can be set to a custom value if specified
Expand Down Expand Up @@ -137,13 +146,15 @@ func (cfg *Config) getOptionsFromConfig() (*exporterOptions, error) {
}

return &exporterOptions{
ingestURL: ingestURL,
apiURL: apiURL,
httpTimeout: cfg.Timeout,
token: cfg.AccessToken,
logDataPoints: cfg.LogDataPoints,
logDimUpdate: cfg.LogDimensionUpdates,
metricTranslator: metricTranslator,
ingestURL: ingestURL,
ingestTLSSettings: cfg.IngestTLSSettings,
apiURL: apiURL,
apiTLSSettings: cfg.APITLSSettings,
httpTimeout: cfg.Timeout,
token: cfg.AccessToken,
logDataPoints: cfg.LogDataPoints,
logDimUpdate: cfg.LogDimensionUpdates,
metricTranslator: metricTranslator,
}, nil
}

Expand Down
43 changes: 32 additions & 11 deletions exporter/signalfxexporter/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"time"

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config/configtls"
"go.opentelemetry.io/collector/consumer"
"go.opentelemetry.io/collector/pdata/plog"
"go.opentelemetry.io/collector/pdata/pmetric"
Expand Down Expand Up @@ -65,13 +66,15 @@ type signalfxExporter struct {
}

type exporterOptions struct {
ingestURL *url.URL
apiURL *url.URL
httpTimeout time.Duration
token string
logDataPoints bool
logDimUpdate bool
metricTranslator *translation.MetricTranslator
ingestURL *url.URL
ingestTLSSettings configtls.TLSClientSetting
apiURL *url.URL
apiTLSSettings configtls.TLSClientSetting
httpTimeout time.Duration
token string
logDataPoints bool
logDimUpdate bool
metricTranslator *translation.MetricTranslator
}

// newSignalFxExporter returns a new SignalFx exporter.
Expand Down Expand Up @@ -108,6 +111,12 @@ func newSignalFxExporter(
transport.MaxIdleConnsPerHost = config.MaxConnections
transport.IdleConnTimeout = 30 * time.Second

ingestTLSCfg, err := config.IngestTLSSettings.LoadTLSConfig()
if err != nil {
return nil, fmt.Errorf("could not load Ingest TLS config: %w", err)
}
transport.TLSClientConfig = ingestTLSCfg

dpClient := &sfxDPClient{
sfxClientBase: sfxClientBase{
ingestURL: options.ingestURL,
Expand All @@ -124,13 +133,19 @@ func newSignalFxExporter(
converter: converter,
}

apiTLSCfg, err := config.APITLSSettings.LoadTLSConfig()
if err != nil {
return nil, fmt.Errorf("could not load API TLS config: %w", err)
}

dimClient := dimensions.NewDimensionClient(
context.Background(),
dimensions.DimensionClientOptions{
Token: options.token,
APIURL: options.apiURL,
LogUpdates: options.logDimUpdate,
Logger: logger,
Token: options.token,
APIURL: options.apiURL,
APITLSConfig: apiTLSCfg,
LogUpdates: options.logDimUpdate,
Logger: logger,
// Duration to wait between property updates. This might be worth
// being made configurable.
SendDelay: 10,
Expand Down Expand Up @@ -178,6 +193,12 @@ func newEventExporter(config *Config, logger *zap.Logger) (*signalfxExporter, er
transport.MaxIdleConnsPerHost = config.MaxConnections
transport.IdleConnTimeout = 30 * time.Second

ingestTLSCfg, err := config.IngestTLSSettings.LoadTLSConfig()
if err != nil {
return nil, fmt.Errorf("could not load Ingest TLS config: %w", err)
}
transport.TLSClientConfig = ingestTLSCfg

eventClient := &sfxEventClient{
sfxClientBase: sfxClientBase{
ingestURL: options.ingestURL,
Expand Down
Loading