Skip to content

Commit

Permalink
fix: Add Chronicle Forwarder Client interface & More Tests (#1415)
Browse files Browse the repository at this point in the history
* Add chronicle client & more tests

* PR feedback

* Address gosec
  • Loading branch information
Miguel Rodriguez authored and dpaasman00 committed Jan 9, 2024
1 parent 90dfd68 commit be42b06
Show file tree
Hide file tree
Showing 5 changed files with 385 additions and 10 deletions.
54 changes: 44 additions & 10 deletions exporter/chronicleforwarderexporter/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"io"
"net"
"os"
"path/filepath"
"strings"

"go.opentelemetry.io/collector/consumer"
Expand All @@ -35,13 +36,40 @@ type chronicleForwarderExporter struct {
logger *zap.Logger
marshaler logMarshaler
endpoint string
chronicleForwarderClient
}

// chronicleForwarderClient is a client for creating connections to Chronicle forwarder. (created for overriding in tests)
//
//go:generate mockery --name chronicleForwarderClient --output ./internal/mocks --with-expecter --filename chronicle_forwarder_client.go --structname MockForwarderClient
type chronicleForwarderClient interface {
Dial(network string, address string) (net.Conn, error)
DialWithTLS(network string, addr string, config *tls.Config) (*tls.Conn, error)
OpenFile(name string) (*os.File, error)
}

type forwarderClient struct {
}

func (fc *forwarderClient) Dial(network string, address string) (net.Conn, error) {
return net.Dial(network, address)
}

func (fc *forwarderClient) DialWithTLS(network string, addr string, config *tls.Config) (*tls.Conn, error) {
return tls.Dial(network, addr, config)
}

func (fc *forwarderClient) OpenFile(name string) (*os.File, error) {
cleanPath := filepath.Clean(name)
return os.OpenFile(cleanPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600)
}

func newExporter(cfg *Config, params exporter.CreateSettings) (*chronicleForwarderExporter, error) {
return &chronicleForwarderExporter{
cfg: cfg,
logger: params.Logger,
marshaler: newMarshaler(*cfg, params.TelemetrySettings),
cfg: cfg,
logger: params.Logger,
marshaler: newMarshaler(*cfg, params.TelemetrySettings),
chronicleForwarderClient: &forwarderClient{},
}, nil
}

Expand Down Expand Up @@ -83,25 +111,31 @@ func (ce *chronicleForwarderExporter) openWriter() (io.WriteCloser, error) {
}

func (ce *chronicleForwarderExporter) openFileWriter() (io.WriteCloser, error) {
return os.OpenFile(ce.cfg.File.Path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600)
return ce.OpenFile(ce.cfg.File.Path)
}

func (ce *chronicleForwarderExporter) openSyslogWriter() (io.WriteCloser, error) {
var conn net.Conn
var err error
if ce.cfg.Syslog.TLSSetting != nil {
tlsConfig, err := ce.cfg.Syslog.TLSSetting.LoadTLSConfig()
var tlsConfig *tls.Config
tlsConfig, err = ce.cfg.Syslog.TLSSetting.LoadTLSConfig()
if err != nil {
return nil, fmt.Errorf("load TLS config: %w", err)
}
conn, err = tls.Dial(ce.cfg.Syslog.NetAddr.Transport, ce.cfg.Syslog.NetAddr.Endpoint, tlsConfig)
conn, err = ce.DialWithTLS(ce.cfg.Syslog.NetAddr.Transport, ce.cfg.Syslog.NetAddr.Endpoint, tlsConfig)

if err != nil {
return nil, fmt.Errorf("dial with tls: %w", err)
}
} else {
conn, err = net.Dial(ce.cfg.Syslog.NetAddr.Transport, ce.cfg.Syslog.NetAddr.Endpoint)
}
conn, err = ce.Dial(ce.cfg.Syslog.NetAddr.Transport, ce.cfg.Syslog.NetAddr.Endpoint)

if err != nil {
return nil, fmt.Errorf("dial: %w", err)
if err != nil {
return nil, fmt.Errorf("dial: %w", err)
}
}

return conn, nil
}

Expand Down
134 changes: 134 additions & 0 deletions exporter/chronicleforwarderexporter/exporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,19 @@ package chronicleforwarderexporter

import (
"context"
"crypto/tls"
"errors"
"log"
"net"
"os"
"testing"
"time"

"github.com/observiq/bindplane-agent/exporter/chronicleforwarderexporter/internal/mocks"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/collector/config/confignet"
"go.opentelemetry.io/collector/config/configtls"
"go.opentelemetry.io/collector/exporter"
)

Expand Down Expand Up @@ -136,3 +141,132 @@ func handleSyslogConnection(t *testing.T, conn net.Conn, logReceived chan bool)
logReceived <- true
conn.Close()
}

func TestOpenWriter(t *testing.T) {
tests := []struct {
name string
setupMock func(*mocks.MockForwarderClient)
expectedError bool
cfg Config
}{
{
name: "Successful File Open",
setupMock: func(mockClient *mocks.MockForwarderClient) {
mockClient.On("OpenFile", "testfile.log").Return(&os.File{}, nil)
},
expectedError: false,
cfg: Config{
ExportType: exportTypeFile,
File: File{
Path: "testfile.log",
},
},
},
{
name: "File Open Error",
setupMock: func(mockClient *mocks.MockForwarderClient) {
mockClient.On("OpenFile", "invalidfile.log").Return(nil, errors.New("error opening file"))
},
expectedError: true,
cfg: Config{
ExportType: exportTypeFile,
File: File{
Path: "invalidfile.log",
},
},
},
{
name: "Successful Syslog Open",
setupMock: func(mockClient *mocks.MockForwarderClient) {
mockClient.On("Dial", "tcp", "localhost:1234").Return(&net.TCPConn{}, nil)
},
expectedError: false,
cfg: Config{
ExportType: exportTypeSyslog,
Syslog: SyslogConfig{
NetAddr: confignet.NetAddr{
Endpoint: "localhost:1234",
Transport: "tcp",
},
},
},
},
{
name: "Syslog Open Error",
setupMock: func(mockClient *mocks.MockForwarderClient) {
mockClient.On("Dial", "tcp", "invalidendpoint").Return(nil, errors.New("error opening syslog"))
},
expectedError: true,
cfg: Config{
ExportType: exportTypeSyslog,
Syslog: SyslogConfig{
NetAddr: confignet.NetAddr{
Endpoint: "invalidendpoint",
Transport: "tcp",
},
},
},
},
{
name: "Successful TLS Dial",
setupMock: func(mockClient *mocks.MockForwarderClient) {
mockClient.On("DialWithTLS", "tcp", "localhost:1234", mock.Anything).Return(&tls.Conn{}, nil)
},
cfg: Config{
ExportType: exportTypeSyslog,
Syslog: SyslogConfig{
NetAddr: confignet.NetAddr{
Endpoint: "localhost:1234",
Transport: "tcp",
},
TLSSetting: &configtls.TLSClientSetting{Insecure: true},
},
},
expectedError: false,
},
{
name: "Failed TLS Dial",
setupMock: func(mockClient *mocks.MockForwarderClient) {
mockClient.On("DialWithTLS", "tcp", "localhost:1234", mock.Anything).Return(nil, errors.New("TLS dial error"))
},
cfg: Config{
ExportType: exportTypeSyslog,
Syslog: SyslogConfig{
NetAddr: confignet.NetAddr{
Endpoint: "localhost:1234",
Transport: "tcp",
},
TLSSetting: &configtls.TLSClientSetting{Insecure: true},
},
},
expectedError: true,
},
}

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
// Create a mock client
mockClient := mocks.NewMockForwarderClient(t)
tc.setupMock(mockClient)

// Create an instance of chronicleForwarderExporter with the mock client
exporter := &chronicleForwarderExporter{
chronicleForwarderClient: mockClient,
cfg: &tc.cfg,
}

// Call openWriter
_, err := exporter.openWriter()

// Assert the outcome
if tc.expectedError {
require.Error(t, err)
} else {
require.NoError(t, err)
}

// Assert mock interactions
mockClient.AssertExpectations(t)
})
}
}
1 change: 1 addition & 0 deletions exporter/chronicleforwarderexporter/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ require (

require (
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/stretchr/objx v0.5.0 // indirect
go.opentelemetry.io/collector/config/configopaque v0.91.0 // indirect
)

Expand Down
1 change: 1 addition & 0 deletions exporter/chronicleforwarderexporter/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
Expand Down
Loading

0 comments on commit be42b06

Please sign in to comment.