Skip to content

Commit

Permalink
[exporter/signalfxexporter] allow user to add their own CA to the cer…
Browse files Browse the repository at this point in the history
…t pool (open-telemetry#16250)

Adding new feature to allow the user to add their own CA to the ingest and api client cert pool.
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 (ex: agent <--> GW setup)

Signed-off-by: Dani Louca <[email protected]>
Co-authored-by: Dmitrii Anoshin <[email protected]>
  • Loading branch information
dloucasfx and dmitryax committed Nov 18, 2022
1 parent 8dd98c9 commit 40e7b46
Show file tree
Hide file tree
Showing 10 changed files with 433 additions and 18 deletions.
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

0 comments on commit 40e7b46

Please sign in to comment.