diff --git a/docs/apis/url.md b/docs/apis/url.md
index 7c7f5869..1233828a 100644
--- a/docs/apis/url.md
+++ b/docs/apis/url.md
@@ -1,17 +1,17 @@
# url API
-The `url` API allows you to retrieve information from an HTTP endpoint.
+The `url` API allows you to retrieve information from an HTTP endpoint.
-* [Basic usage](#Basicusage)
-* [Use POST/PUT methods with a body](#UsePOSTPUTmethodswithabody)
-* [Configure your HTTPS connections](#ConfigureyourHTTPSconnections)
-* [Specify a common base URL](#SpecifyacommonbaseURL)
-* [URL with cache for later processing](#URLwithcacheforlaterprocessing)
-* [Include response headers on sample](#ReturnResponseHeaders)
+- [Basic usage](#Basicusage)
+- [Use POST/PUT methods with a body](#UsePOSTPUTmethodswithabody)
+- [Configure your HTTPS connections](#ConfigureyourHTTPSconnections)
+- [Specify a common base URL](#SpecifyacommonbaseURL)
+- [URL with cache for later processing](#URLwithcacheforlaterprocessing)
+- [Include response headers on sample](#ReturnResponseHeaders)
-## Basic usage
+## Basic usage
-```yaml
+```yaml
name: example
apis:
- event_type: ExampleSample
@@ -22,29 +22,31 @@ apis:
The above Flex configuration retrieves a JSON file containing a set of metrics from the provided URL. Note that the `url` key can be followed by a `headers` section, which allows specifying HTTP headers.
-## Use POST/PUT methods with a body
+## Use POST/PUT methods with a body
To specify a `POST` or `PUT` request with a body, use the `method` and `payload` properties.
```yaml
-name: httpPostExample
-apis:
+name: httpPostExample
+apis:
- name: httpPost
url: https://jsonplaceholder.typicode.com/posts
method: POST
- payload: >
+ payload: >
{"title": "foo","body": "bar","userId": 1}
```
-## Configure your HTTPS connections
+## Configure your HTTPS connections
When using TLS endpoints with self-signed certificates, define a `tls_config` section with any of the following items:
-| Name | Type | Default | Description |
-|---:|:---:|:---:|---|
-| `enable` | bool | `false` | Set to `true` to enable custom TLS configuration. Requires `ca` to be defined if enabled. |
-| `insecure_skip_verify` | bool | `false` | Set to `true` to skip the verification of TLS certificates. |
-| `ca` | string | _Empty_ | The Certificate Authority PEM certificate, in case your HTTPS endpoint has self-signed certificates. |
+| Name | Type | Default | Description |
+| ---------------------: | :----: | :-----: | ------------------------------------------------------------------------------------------------------------ |
+| `enable` | bool | `false` | Set to `true` to enable custom TLS configuration. Requires `ca` to be defined if enabled. |
+| `insecure_skip_verify` | bool | `false` | Set to `true` to skip the verification of TLS certificates. |
+| `ca` | string | _Empty_ | The Certificate Authority PEM certificate, in case your HTTPS endpoint has self-signed certificates. |
+| `cert` | string | _Empty_ | PEM encoded certificate (must be used with `key`), in case your HTTPS endpoint has self-signed certificates. |
+| `key` | string | _Empty_ | PEM encoded key (must be used with `cert`), in case your HTTPS endpoint has self-signed certificates. |
### TLS configuration example:
@@ -60,18 +62,18 @@ apis:
ca: /etc/bundles/my-ca-cert.pem
```
-## Specify a common base URL
+## Specify a common base URL
When you have to query several different URLs, specifying a `base_url` under `global` can be quite helpful, as it allows you to provide URL path segment in `url` fields instead of full URLs.
-### Base URL example
+### Base URL example
```yaml
name: consulFlex
global:
- base_url: http://consul-host/v1/
- headers:
- X-Consul-Token: my-root-consul-token
+ base_url: http://consul-host/v1/
+ headers:
+ X-Consul-Token: my-root-consul-token
apis:
- event_type: ConsulHealthSample
url: health/service/consul
@@ -81,7 +83,7 @@ apis:
url: agent/members
```
-## URL with cache for later processing
+## URL with cache for later processing
URL invocations are cached to avoid having to query them repeatedly. Use `cache` under `command` to read cached data.
@@ -101,42 +103,52 @@ apis:
- expression: Active connections:\s(\S+)
keys: [net.connectionsActive]
- expression: \s?(\d+)\s(\d+)\s(\d+)
- keys: [net.connectionsAcceptedPerSecond, net.handledPerSecond, net.requestsPerSecond]
+ keys:
+ [
+ net.connectionsAcceptedPerSecond,
+ net.handledPerSecond,
+ net.requestsPerSecond,
+ ]
- expression: Reading:\s(\d+)\s\S+\s(\d+)\s\S+\s(\d+)
- keys: [net.connectionsReading, net.connectionsWriting, net.connectionsWaiting]
+ keys:
+ [
+ net.connectionsReading,
+ net.connectionsWriting,
+ net.connectionsWaiting,
+ ]
math:
net.connectionsDroppedPerSecond: ${net.connectionsAcceptedPerSecond} - ${net.handledPerSecond}
```
-## Include response headers on sample
+## Include response headers on sample
To include response headers on the metric sample set `return_headers` attribute to true.
-### Return headers example
+### Return headers example
```yaml
name: example
apis:
- name: ExampleSample
url: https://my-host:8443/admin/metrics/1
- return_headers: true
+ return_headers: true
```
Given the following output for each metric:
```json
{
- "event_type": "ExampleSample",
- "integration_name": "com.newrelic.nri-flex",
- "integration_version": "version-number",
- "id": 1,
- "completed": "true",
- "api.StatusCode": 200,
- "api.header.Access-Control-Allow-Credentials": "[true]",
- "api.header.Age": "[4459]",
- "api.header.Content-Type": "[application/json; charset=utf-8]",
- "api.header.Date": "[Mon, 25 May 2020 16:23:53 GMT]",
- "api.header.Expires": "[-1]",
- "api.header.Retry-Count": "[0]"
+ "event_type": "ExampleSample",
+ "integration_name": "com.newrelic.nri-flex",
+ "integration_version": "version-number",
+ "id": 1,
+ "completed": "true",
+ "api.StatusCode": 200,
+ "api.header.Access-Control-Allow-Credentials": "[true]",
+ "api.header.Age": "[4459]",
+ "api.header.Content-Type": "[application/json; charset=utf-8]",
+ "api.header.Date": "[Mon, 25 May 2020 16:23:53 GMT]",
+ "api.header.Expires": "[-1]",
+ "api.header.Retry-Count": "[0]"
}
-```
+```
diff --git a/internal/inputs/http.go b/internal/inputs/http.go
index 5f1f0f4d..0d705221 100644
--- a/internal/inputs/http.go
+++ b/internal/inputs/http.go
@@ -242,6 +242,15 @@ func setRequestOptions(request *gorequest.SuperAgent, yml load.Config, api load.
}
}
+ if yml.Global.TLSConfig.Key != "" && yml.Global.TLSConfig.Cert != "" {
+ cert, err := tls.LoadX509KeyPair(yml.Global.TLSConfig.Cert, yml.Global.TLSConfig.Key)
+ if err != nil {
+ load.Logrus.WithError(err).Error("http: failed to load x509 keypair")
+ } else {
+ tmpGlobalTLSConfig.Certificates = []tls.Certificate{cert}
+ }
+ }
+
request = request.TLSClientConfig(&tmpGlobalTLSConfig)
if api.TLSConfig.Enable {
@@ -260,6 +269,16 @@ func setRequestOptions(request *gorequest.SuperAgent, yml load.Config, api load.
tmpAPITLSConfig.RootCAs = rootCAs
}
}
+
+ if api.TLSConfig.Key != "" && api.TLSConfig.Cert != "" {
+ cert, err := tls.LoadX509KeyPair(api.TLSConfig.Cert, api.TLSConfig.Key)
+ if err != nil {
+ load.Logrus.WithError(err).Error("http: failed to load x509 keypair")
+ } else {
+ tmpAPITLSConfig.Certificates = []tls.Certificate{cert}
+ }
+ }
+
request = request.TLSClientConfig(&tmpAPITLSConfig)
}
diff --git a/internal/load/load.go b/internal/load/load.go
index d4dbf5c2..778ff57d 100644
--- a/internal/load/load.go
+++ b/internal/load/load.go
@@ -238,7 +238,9 @@ type TLSConfig struct {
InsecureSkipVerify bool `yaml:"insecure_skip_verify"`
MinVersion uint16 `yaml:"min_version"`
MaxVersion uint16 `yaml:"max_version"`
- Ca string `yaml:"ca"` // path to ca to read
+ Ca string `yaml:"ca"` // path to ca to read
+ Key string `yaml:"key"` // path to key to read
+ Cert string `yaml:"cert"` // path to cert to read
}
// SampleMerge merge multiple samples into one (will remove previous samples)