diff --git a/internal/config/config.go b/internal/config/config.go index 5c604cfa8..ffe8f0cb3 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -327,23 +327,9 @@ func resolveCollector(allowedDirs []string) (*Collector, error) { Health: &healthCheck, } - if col.Receivers.OtlpReceivers != nil { - for _, receiver := range col.Receivers.OtlpReceivers { - if receiver.TLS != nil { - // If generate_self_signed_cert is true - if receiver.TLS.GenerateSelfSignedCert { - slog.Warn("self-signed certificate for collector requested") - _, err := selfsignedcert.GenerateSelfSignedCert(DefCollectorTLSCertPath, DefCollectorTLSKeyPath) - if err != nil { - return nil, fmt.Errorf("failed to generate self-signed certificate: %w", err) - } - - // update the receiver's TLS paths if they are blank. - receiver.TLS.Cert = DefCollectorTLSCertPath - receiver.TLS.Key = DefCollectorTLSKeyPath - } - } - } + // Check for self-signed certificate true in Agent conf + if err = handleSelfSignedCertificates(col); err != nil { + return nil, err } err = col.Validate(allowedDirs) @@ -354,6 +340,30 @@ func resolveCollector(allowedDirs []string) (*Collector, error) { return col, nil } +// generate self-signed certificate for OTEL receiver +// nolint: revive +func handleSelfSignedCertificates(col *Collector) error { + if col.Receivers.OtlpReceivers != nil { + for _, receiver := range col.Receivers.OtlpReceivers { + if receiver.TLS != nil && receiver.TLS.GenerateSelfSignedCert { + slog.Warn("self-signed certificate for collector requested") + if _, err := selfsignedcert.GenerateSelfSignedCert( + DefCollectorTLSCertPath, + DefCollectorTLSKeyPath, + ); err != nil { + return fmt.Errorf("failed to generate self-signed certificate: %w", err) + } + + // Update viper's TLS paths with defaults + receiver.TLS.Cert = DefCollectorTLSCertPath + receiver.TLS.Key = DefCollectorTLSKeyPath + } + } + } + + return nil +} + func resolveCommand() *Command { if !viperInstance.IsSet(CommandRootKey) { return nil diff --git a/pkg/tls/self_signed_cert.go b/pkg/tls/self_signed_cert.go index d84c55e7f..35996eb76 100644 --- a/pkg/tls/self_signed_cert.go +++ b/pkg/tls/self_signed_cert.go @@ -14,6 +14,7 @@ import ( "crypto/x509" "crypto/x509/pkix" "encoding/pem" + "errors" "fmt" "log/slog" "math/big" @@ -21,16 +22,21 @@ import ( "time" ) -var organization string = "F5 Inc." +const ( + organization = "F5 Inc." + filePermissions = 0o600 +) func GenerateSelfSignedCert(certPath, keyPath string) (*tls.Certificate, error) { // Skip gen if cert or key files exist if _, err := os.Stat(certPath); err == nil { slog.Warn("certificate file already exists, skipping self-signed certificate generation.") - return nil, nil - } else if _, err := os.Stat(keyPath); err == nil { + return nil, errors.New("certificate file already exists") + } + + if _, err := os.Stat(keyPath); err == nil { slog.Warn("key file already exists, skipping self-signed certificate generation.") - return nil, nil + return nil, errors.New("key file already exists") } priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) @@ -66,13 +72,13 @@ func GenerateSelfSignedCert(certPath, keyPath string) (*tls.Certificate, error) keyPEM := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: keyBytes}) // Write the certificate to a file - err = os.WriteFile(certPath, certPEM, 0600) + err = os.WriteFile(certPath, certPEM, filePermissions) if err != nil { return nil, fmt.Errorf("failed to write certificate file: %w", err) } // Write the private key to a file - err = os.WriteFile(keyPath, keyPEM, 0600) + err = os.WriteFile(keyPath, keyPEM, filePermissions) if err != nil { return nil, fmt.Errorf("failed to write key file: %w", err) } diff --git a/pkg/tls/self_signed_cert_test.go b/pkg/tls/self_signed_cert_test.go index c7aa13e27..ff1fb4c63 100644 --- a/pkg/tls/self_signed_cert_test.go +++ b/pkg/tls/self_signed_cert_test.go @@ -12,6 +12,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestGenerateSelfSignedCert(t *testing.T) { @@ -26,8 +27,8 @@ func TestGenerateSelfSignedCert(t *testing.T) { // Test case 1: Cert file already exists t.Run("cert file exists", func(t *testing.T) { // Create dummy cert file - err := os.WriteFile(certPath, []byte("dummy cert"), 0600) - assert.NoError(t, err) + err := os.WriteFile(certPath, []byte("dummy cert"), 0o600) + require.NoError(t, err) // Ensure keyPath does not exist err = os.Remove(keyPath) @@ -36,15 +37,15 @@ func TestGenerateSelfSignedCert(t *testing.T) { } cert, err := GenerateSelfSignedCert(certPath, keyPath) - assert.NoError(t, err) + require.NoError(t, err) assert.Nil(t, cert) }) // Test case 2: Key file already exists t.Run("key file exists", func(t *testing.T) { // Create dummy key file - err := os.WriteFile(keyPath, []byte("dummy key"), 0600) - assert.NoError(t, err) + err := os.WriteFile(keyPath, []byte("dummy key"), 0o600) + require.NoError(t, err) // Ensure certPath does not exist err = os.Remove(certPath) @@ -54,13 +55,13 @@ func TestGenerateSelfSignedCert(t *testing.T) { // Generate certificate cert, err := GenerateSelfSignedCert(certPath, keyPath) - assert.NoError(t, err) + require.NoError(t, err) assert.Nil(t, cert) // Add more assertions if needed to check logs or other side effects }) - // Test case 2: Error writing certificate file + // Test case 3: Error writing certificate file t.Run("error writing certificate file", func(t *testing.T) { // Ensure the certificate and key files do not exist os.Remove(certPath) @@ -69,12 +70,12 @@ func TestGenerateSelfSignedCert(t *testing.T) { // Use an invalid path to simulate a write error invalidPath := "/dev/null/cert.pem" // Use a path that is guaranteed to fail cert, err := GenerateSelfSignedCert(invalidPath, keyPath) - assert.Error(t, err) + require.NoError(t, err) assert.Nil(t, cert) assert.Contains(t, err.Error(), "failed to write certificate file") }) - // Test case 3: Error writing key file + // Test case 4: Error writing key file t.Run("error writing key file", func(t *testing.T) { // Ensure the certificate and key files do not exist os.Remove(certPath) @@ -83,7 +84,7 @@ func TestGenerateSelfSignedCert(t *testing.T) { // Use an invalid path to simulate a write error invalidPath := "/dev/null/key.pem" // Use a path that is guaranteed to fail cert, err := GenerateSelfSignedCert(certPath, invalidPath) - assert.Error(t, err) + require.NoError(t, err) assert.Nil(t, cert) assert.Contains(t, err.Error(), "failed to write key file") }) @@ -95,14 +96,14 @@ func TestGenerateSelfSignedCert(t *testing.T) { os.Remove(keyPath) cert, err := GenerateSelfSignedCert(certPath, keyPath) - assert.NoError(t, err) + require.NoError(t, err) assert.NotNil(t, cert) // Verify that the files were created _, err = os.Stat(certPath) - assert.NoError(t, err) + require.NoError(t, err) _, err = os.Stat(keyPath) - assert.NoError(t, err) + require.NoError(t, err) // Verify that the cert is a valid tls.Certificate assert.IsType(t, &tls.Certificate{}, cert)