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

[receiver/tlscheck] Implement Scraper #35823

Open
wants to merge 75 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 67 commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
2863b29
[receiver/tlscheck] Implement Scraper
michael-burt Oct 22, 2024
b090224
Revert to 56e05fced
michael-burt Oct 23, 2024
b592e49
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 23, 2024
d032cbf
[receiver/tlscheck] Implement Scraper
michael-burt Oct 23, 2024
df87bdb
[receiver/tlscheck] Implement Scraper
michael-burt Oct 23, 2024
9f0718d
[receiver/tlscheck] Implement Scraper
michael-burt Oct 23, 2024
4d9bc28
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 23, 2024
2e73fca
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 23, 2024
4e66e6a
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 23, 2024
23e70a7
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 23, 2024
ea6e4f1
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 23, 2024
ac22ff0
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 23, 2024
baa8f9a
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 23, 2024
c1384c6
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 23, 2024
8f99e99
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 23, 2024
dea8147
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 23, 2024
ecf2b59
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 24, 2024
d0a4bb9
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 24, 2024
816b4ee
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 24, 2024
43e3072
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 24, 2024
e6e627d
use confignet tcp client
michael-burt Oct 24, 2024
93ad304
refactor scrape
michael-burt Oct 24, 2024
4343e1b
generate
michael-burt Oct 24, 2024
ed32280
fixes
michael-burt Oct 24, 2024
8b79865
go tidy
michael-burt Oct 24, 2024
3ce49df
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 25, 2024
d71ac71
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 25, 2024
ce6ec50
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 25, 2024
79e5cd8
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 28, 2024
1f316fb
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 28, 2024
f01cdfb
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 29, 2024
8aac763
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 29, 2024
533c8a7
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 30, 2024
d3aca80
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 30, 2024
2b156c8
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 30, 2024
e9585e4
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 30, 2024
ae6b594
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 31, 2024
1839c07
Merge branch 'main' into tlscheckreceiver
michael-burt Oct 31, 2024
e6c4158
Merge branch 'main' into tlscheckreceiver
michael-burt Nov 1, 2024
dbd4b44
Merge branch 'main' into tlscheckreceiver
michael-burt Nov 1, 2024
7151d26
Merge branch 'main' into tlscheckreceiver
michael-burt Nov 2, 2024
f5cc24d
Merge branch 'main' into tlscheckreceiver
michael-burt Nov 4, 2024
3781e27
Merge branch 'main' into tlscheckreceiver
michael-burt Nov 4, 2024
cfe7db2
Merge branch 'main' into tlscheckreceiver
michael-burt Nov 4, 2024
711cdc2
address PR comments
michael-burt Nov 4, 2024
94383a7
Merge branch 'main' into tlscheckreceiver
michael-burt Nov 5, 2024
cd32244
Merge branch 'main' into tlscheckreceiver
michael-burt Nov 6, 2024
c94bdab
Merge branch 'main' into tlscheckreceiver
michael-burt Nov 6, 2024
f0a279c
Merge branch 'main' into tlscheckreceiver
michael-burt Nov 7, 2024
c537d1a
[receiver/tlscheck] Implement Scraper
michael-burt Nov 7, 2024
0e023ef
Merge branch 'main' into tlscheckreceiver
michael-burt Nov 7, 2024
404cac8
Merge branch 'main' into tlscheckreceiver
michael-burt Nov 15, 2024
e53c1cf
Merge branch 'main' into tlscheckreceiver
michael-burt Nov 16, 2024
8a6dc9c
merge main
michael-burt Nov 20, 2024
eb37ea7
Merge branch 'main' into tlscheckreceiver
michael-burt Nov 20, 2024
71e0049
Merge branch 'main' into tlscheckreceiver
michael-burt Nov 20, 2024
76a7527
Merge branch 'main' into tlscheckreceiver
michael-burt Nov 20, 2024
97354b0
Merge branch 'main' into tlscheckreceiver
michael-burt Nov 20, 2024
1170f31
Merge branch 'main' into tlscheckreceiver
michael-burt Nov 21, 2024
e3ee109
Merge branch 'main' into tlscheckreceiver
michael-burt Nov 21, 2024
bddb4fa
Merge branch 'main' into tlscheckreceiver
michael-burt Nov 23, 2024
0279276
Merge branch 'main' into tlscheckreceiver
michael-burt Nov 24, 2024
7043c57
lint
michael-burt Nov 25, 2024
cb5ff2a
Merge branch 'main' into tlscheckreceiver
michael-burt Nov 25, 2024
af35413
Merge branch 'main' into tlscheckreceiver
michael-burt Nov 25, 2024
0229dd8
address PR comments
michael-burt Nov 26, 2024
8ad0407
lint
michael-burt Nov 26, 2024
561c42d
[receiver/tlscheck] Implement Scraper
michael-burt Dec 7, 2024
d841866
[receiver/tlscheck] Implement Scraper
michael-burt Dec 7, 2024
db44434
[receiver/tlscheck] Implement Scraper
michael-burt Dec 7, 2024
1204e18
[receiver/tlscheck] Implement Scraper
michael-burt Dec 7, 2024
86729ca
merge main and remove ScraperHelper
michael-burt Dec 12, 2024
985ec4f
fix import
michael-burt Dec 12, 2024
26a44e2
fix import
michael-burt Dec 12, 2024
0803b58
cleanup
michael-burt Dec 12, 2024
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
27 changes: 27 additions & 0 deletions .chloggen/tlscheckreceiver-implementation.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Use this changelog template to create an entry for release notes.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: breaking

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

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Implement TLS Check Receiver for host-based checks

# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
issues: [35842]

# (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: Changing configuration scheme to use standard confignet TCP client

# If your change doesn't affect end users or the exported elements of any package,
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
# Optional: The change log or logs in which this entry should be included.
# e.g. '[user]' or '[user, api]'
# Include 'user' if the change is relevant to end users.
# Include 'api' if there is a change to a library API.
# Default: '[user]'
change_logs: [user]
11 changes: 9 additions & 2 deletions receiver/tlscheckreceiver/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,19 @@ By default, the TLS Check Receiver will emit a single metric, `tlscheck.time_lef

## Example Configuration

Targets are

```yaml
receivers:
tlscheck:
targets:
- url: https://example.com
- url: https://foobar.com:8080
- endpoint: example.com:443
dialer:
timeout: 15s
- endpoint: foobar.com:8080
dialer:
timeout: 15s
- endpoint: localhost:10901
```

## Certificate Verification
Expand Down
52 changes: 34 additions & 18 deletions receiver/tlscheckreceiver/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ package tlscheckreceiver // import "github.com/open-telemetry/opentelemetry-coll
import (
"errors"
"fmt"
"net/url"
"net"
"strconv"
"strings"

"go.opentelemetry.io/collector/config/confignet"
"go.opentelemetry.io/collector/receiver/scraperhelper"
"go.uber.org/multierr"

Expand All @@ -16,47 +19,60 @@ import (

// Predefined error responses for configuration validation failures
var (
errMissingURL = errors.New(`"url" must be specified`)
errInvalidURL = errors.New(`"url" must be in the form of <scheme>://<hostname>[:<port>]`)
errInvalidEndpoint = errors.New(`"endpoint" must be in the form of <hostname>:<port>`)
)

// Config defines the configuration for the various elements of the receiver agent.
type Config struct {
scraperhelper.ControllerConfig `mapstructure:",squash"`
metadata.MetricsBuilderConfig `mapstructure:",squash"`
Targets []*targetConfig `mapstructure:"targets"`
Targets []*confignet.TCPAddrConfig `mapstructure:"targets"`
}

type targetConfig struct {
URL string `mapstructure:"url"`
func validatePort(port string) error {
portNum, err := strconv.Atoi(port)
if err != nil {
return fmt.Errorf("provided port is not a number: %s", port)
}
if portNum < 1 || portNum > 65535 {
return fmt.Errorf("provided port is out of valid range (1-65535): %d", portNum)
}
return nil
}

// Validate validates the configuration by checking for missing or invalid fields
func (cfg *targetConfig) Validate() error {
func validateTarget(cfg *confignet.TCPAddrConfig) error {
var err error

if cfg.URL == "" {
err = multierr.Append(err, errMissingURL)
} else {
_, parseErr := url.ParseRequestURI(cfg.URL)
if parseErr != nil {
err = multierr.Append(err, fmt.Errorf("%s: %w", errInvalidURL.Error(), parseErr))
}
if cfg.Endpoint == "" {
return ErrMissingTargets
}

if strings.Contains(cfg.Endpoint, "://") {
return fmt.Errorf("endpoint contains a scheme, which is not allowed: %s", cfg.Endpoint)
}

_, port, parseErr := net.SplitHostPort(cfg.Endpoint)
if parseErr != nil {
return fmt.Errorf("%s: %w", errInvalidEndpoint.Error(), parseErr)
}

portParseErr := validatePort(port)
if portParseErr != nil {
return fmt.Errorf("%s: %w", errInvalidEndpoint.Error(), portParseErr)
}

return err
}

// Validate validates the configuration by checking for missing or invalid fields
func (cfg *Config) Validate() error {
var err error

if len(cfg.Targets) == 0 {
err = multierr.Append(err, errMissingURL)
err = multierr.Append(err, ErrMissingTargets)
}

for _, target := range cfg.Targets {
err = multierr.Append(err, target.Validate())
err = multierr.Append(err, validateTarget(target))
}

return err
Expand Down
65 changes: 47 additions & 18 deletions receiver/tlscheckreceiver/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ package tlscheckreceiver // import "github.com/open-telemetry/opentelemetry-coll
import (
"fmt"
"testing"
"time"

"github.com/stretchr/testify/require"
"go.opentelemetry.io/collector/config/confignet"
"go.opentelemetry.io/collector/receiver/scraperhelper"
)

Expand All @@ -18,61 +20,88 @@ func TestValidate(t *testing.T) {
expectedErr error
}{
{
desc: "missing url",
desc: "missing targets",
cfg: &Config{
Targets: []*targetConfig{},
Targets: []*confignet.TCPAddrConfig{},
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
},
expectedErr: errMissingURL,
expectedErr: ErrMissingTargets,
},
{
desc: "invalid url",
desc: "invalid endpoint",
cfg: &Config{
Targets: []*targetConfig{
Targets: []*confignet.TCPAddrConfig{
{
URL: "invalid://endpoint: 12efg",
Endpoint: "bad-endpoint: 12efg",
DialerConfig: confignet.DialerConfig{
Timeout: 12 * time.Second,
},
},
},
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
},
expectedErr: fmt.Errorf("%w: %s", errInvalidURL, `parse "invalid://endpoint: 12efg": invalid port ": 12efg" after host`),
expectedErr: fmt.Errorf("%w: %s", errInvalidEndpoint, "provided port is not a number: 12efg"),
},
{
desc: "invalid config with multiple targets",
cfg: &Config{
Targets: []*targetConfig{
Targets: []*confignet.TCPAddrConfig{
{
URL: "invalid://endpoint: 12efg",
Endpoint: "endpoint: 12efg",
},
{
URL: "https://example.com",
Endpoint: "https://example.com:80",
},
},
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
},
expectedErr: fmt.Errorf("%w: %s", errInvalidURL, `parse "invalid://endpoint: 12efg": invalid port ": 12efg" after host`),
expectedErr: fmt.Errorf("%w: %s", errInvalidEndpoint, `provided port is not a number: 12efg; endpoint contains a scheme, which is not allowed: https://example.com:80`),
},
{
desc: "missing scheme",
desc: "port out of range",
cfg: &Config{
Targets: []*targetConfig{
Targets: []*confignet.TCPAddrConfig{
{
URL: "www.opentelemetry.io/docs",
Endpoint: "www.opentelemetry.io:67000",
},
},
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
},
expectedErr: fmt.Errorf("%w: %s", errInvalidURL, `parse "www.opentelemetry.io/docs": invalid URI for request`),
expectedErr: fmt.Errorf("%w: %s", errInvalidEndpoint, `provided port is out of valid range (1-65535): 67000`),
},
{
desc: "missing port",
cfg: &Config{
Targets: []*confignet.TCPAddrConfig{
{
Endpoint: "www.opentelemetry.io/docs",
},
},
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
},
expectedErr: fmt.Errorf("%w: %s", errInvalidEndpoint, `address www.opentelemetry.io/docs: missing port in address`),
},
{
desc: "valid config",
cfg: &Config{
Targets: []*targetConfig{
Targets: []*confignet.TCPAddrConfig{
{
Endpoint: "opentelemetry.io:443",
DialerConfig: confignet.DialerConfig{
Timeout: 3 * time.Second,
},
},
{
URL: "https://opentelemetry.io",
Endpoint: "opentelemetry.io:8080",
DialerConfig: confignet.DialerConfig{
Timeout: 1 * time.Second,
},
},
{
URL: "https://opentelemetry.io:80/docs",
Endpoint: "111.222.33.44:10000",
DialerConfig: confignet.DialerConfig{
Timeout: 5 * time.Second,
},
},
},
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
Expand Down
7 changes: 1 addition & 6 deletions receiver/tlscheckreceiver/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,4 @@ Time in seconds until certificate expiry, as specified by `NotAfter` field in th
| ---- | ----------- | ------ |
| tlscheck.x509.issuer | The entity that issued the certificate. | Any Str |
| tlscheck.x509.cn | The commonName in the subject of the certificate. | Any Str |

## Resource Attributes

| Name | Description | Values | Enabled |
| ---- | ----------- | ------ | ------- |
| tlscheck.url | Url at which the certificate was accessed. | Any Str | true |
| tlscheck.endpoint | Endpoint at which the certificate was accessed. | Any Str |
10 changes: 6 additions & 4 deletions receiver/tlscheckreceiver/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"errors"

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config/confignet"
"go.opentelemetry.io/collector/consumer"
"go.opentelemetry.io/collector/receiver"
"go.opentelemetry.io/collector/receiver/scraperhelper"
Expand All @@ -17,7 +18,6 @@ import (

var errConfigNotTLSCheck = errors.New(`invalid config`)

// NewFactory creates a new filestats receiver factory.
func NewFactory() receiver.Factory {
return receiver.NewFactory(
metadata.Type,
Expand All @@ -26,10 +26,12 @@ func NewFactory() receiver.Factory {
}

func newDefaultConfig() component.Config {
cfg := scraperhelper.NewDefaultControllerConfig()

return &Config{
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
ControllerConfig: cfg,
MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig(),
Targets: []*targetConfig{},
Targets: []*confignet.TCPAddrConfig{},
}
}

Expand All @@ -44,7 +46,7 @@ func newReceiver(
return nil, errConfigNotTLSCheck
}

mp := newScraper(tlsCheckConfig, settings)
mp := newScraper(tlsCheckConfig, settings, getConnectionState)
s, err := scraperhelper.NewScraperWithoutType(mp.scrape)
if err != nil {
return nil, err
Expand Down
3 changes: 2 additions & 1 deletion receiver/tlscheckreceiver/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

"github.com/stretchr/testify/require"
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config/confignet"
"go.opentelemetry.io/collector/consumer/consumertest"
"go.opentelemetry.io/collector/receiver/receivertest"
"go.opentelemetry.io/collector/receiver/scraperhelper"
Expand Down Expand Up @@ -40,7 +41,7 @@ func TestNewFactory(t *testing.T) {
InitialDelay: time.Second,
},
MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig(),
Targets: []*targetConfig{},
Targets: []*confignet.TCPAddrConfig{},
}

require.Equal(t, expectedCfg, factory.CreateDefaultConfig())
Expand Down
2 changes: 1 addition & 1 deletion receiver/tlscheckreceiver/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ require (
github.com/stretchr/testify v1.9.0
go.opentelemetry.io/collector/component v0.114.0
go.opentelemetry.io/collector/component/componenttest v0.114.0
go.opentelemetry.io/collector/config/confignet v1.20.0
go.opentelemetry.io/collector/confmap v1.20.0
go.opentelemetry.io/collector/consumer v0.114.0
go.opentelemetry.io/collector/consumer/consumertest v0.114.0
go.opentelemetry.io/collector/filter v0.114.0
go.opentelemetry.io/collector/pdata v1.20.0
go.opentelemetry.io/collector/receiver v0.114.0
go.opentelemetry.io/collector/receiver/receivertest v0.114.0
Expand Down
4 changes: 2 additions & 2 deletions receiver/tlscheckreceiver/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading