Skip to content

Commit

Permalink
[chore][receiver/sqlserver] Add direct connection config options (#32176
Browse files Browse the repository at this point in the history
)

**Description:** <Describe what has changed.>
<!--Ex. Fixing a bug - Describe the bug and how this fixes the issue.
Ex. Adding a feature - Explain what this achieves.-->
This adds config options for direct connection to a SQL server instance.
For the sake of PR size, this adds no functionality, it's simply config
options and validation.

**Link to tracking Issue:** <Issue number if applicable>
This was originally part of
#31915,
but I'm breaking this out to make the original PR a more manageable
size.


#30297

**Testing:** <Describe what testing was performed and which tests were
added.>
Existing tests and added tests are all passing.

**Documentation:** <Describe the documentation added.>
No documentation on purpose. The added config options currently have no
impact on functionality, so users shouldn't be aware of this, and
shouldn't try to use them yet.
  • Loading branch information
crobert-1 authored Apr 16, 2024
1 parent 62df686 commit a980e8e
Show file tree
Hide file tree
Showing 9 changed files with 257 additions and 11 deletions.
25 changes: 19 additions & 6 deletions receiver/sqlserverreceiver/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package sqlserverreceiver // import "github.com/open-telemetry/opentelemetry-col
import (
"fmt"

"go.opentelemetry.io/collector/config/configopaque"
"go.opentelemetry.io/collector/receiver/scraperhelper"

"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/sqlserverreceiver/internal/metadata"
Expand All @@ -15,16 +16,28 @@ import (
type Config struct {
scraperhelper.ControllerConfig `mapstructure:",squash"`
metadata.MetricsBuilderConfig `mapstructure:",squash"`
InstanceName string `mapstructure:"instance_name"`
ComputerName string `mapstructure:"computer_name"`

InstanceName string `mapstructure:"instance_name"`
ComputerName string `mapstructure:"computer_name"`

// The following options currently do nothing. Functionality will be added in a future PR.
Password configopaque.String `mapstructure:"password"`
Port uint `mapstructure:"port"`
Server string `mapstructure:"server"`
Username string `mapstructure:"username"`
}

func (cfg *Config) Validate() error {
if cfg.InstanceName != "" && cfg.ComputerName == "" {
return fmt.Errorf("'instance_name' may not be specified without 'computer_name'")
err := cfg.validateInstanceAndComputerName()
if err != nil {
return err
}
if cfg.InstanceName == "" && cfg.ComputerName != "" {
return fmt.Errorf("'computer_name' may not be specified without 'instance_name'")

if !directDBConnectionEnabled(cfg) {
if cfg.Server != "" || cfg.Username != "" || string(cfg.Password) != "" {
return fmt.Errorf("Found one or more of the following configuration options set: [server, port, username, password]. " +
"All of these options must be configured to directly connect to a SQL Server instance.")
}
}

return nil
Expand Down
10 changes: 10 additions & 0 deletions receiver/sqlserverreceiver/config_others.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

//go:build !windows

package sqlserverreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/sqlserverreceiver"

func (cfg *Config) validateInstanceAndComputerName() error {
return nil
}
88 changes: 88 additions & 0 deletions receiver/sqlserverreceiver/config_others_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

//go:build !windows

package sqlserverreceiver

import (
"testing"

"github.com/stretchr/testify/require"
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/receiver/scraperhelper"

"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/sqlserverreceiver/internal/metadata"
)

func TestValidateOtherOS(t *testing.T) {
testCases := []struct {
desc string
cfg *Config
expectedSuccess bool
}{
{
desc: "valid config",
cfg: &Config{
MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig(),
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
},
expectedSuccess: true,
}, {
desc: "valid config with no metric settings",
cfg: &Config{
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
},
expectedSuccess: true,
},
{
desc: "default config is valid",
cfg: createDefaultConfig().(*Config),
expectedSuccess: true,
},
{
desc: "valid config with both names set",
cfg: &Config{
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
ComputerName: "ComputerName",
InstanceName: "InstanceName",
},
expectedSuccess: true,
},
{
desc: "valid config with instance_name but not computer_name",
cfg: &Config{
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
InstanceName: "InstanceName",
},
expectedSuccess: true,
},
{
desc: "valid config with computer_name but not instance_name",
cfg: &Config{
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
ComputerName: "ComputerName",
},
expectedSuccess: true,
},
{
desc: "valid config with both instance and computer name",
cfg: &Config{
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
ComputerName: "ComputerName",
InstanceName: "InstanceName",
},
expectedSuccess: true,
},
}

for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
if tc.expectedSuccess {
require.NoError(t, component.ValidateConfig(tc.cfg))
} else {
require.Error(t, component.ValidateConfig(tc.cfg))
}
})
}
}
38 changes: 33 additions & 5 deletions receiver/sqlserverreceiver/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,58 @@ import (

func TestValidate(t *testing.T) {
testCases := []struct {
desc string
cfg *Config
desc string
cfg *Config
expectedSuccess bool
}{
{
desc: "valid config",
cfg: &Config{
MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig(),
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
},
expectedSuccess: true,
}, {
desc: "valid config with no metric settings",
cfg: &Config{
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
},
expectedSuccess: true,
},
{
desc: "default config is valid",
cfg: createDefaultConfig().(*Config),
desc: "default config is valid",
cfg: createDefaultConfig().(*Config),
expectedSuccess: true,
},
{
desc: "invalid config with partial direct connect settings",
cfg: &Config{
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
Server: "0.0.0.0",
Username: "sa",
},
expectedSuccess: false,
},
{
desc: "valid config with all direct connection settings",
cfg: &Config{
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
Server: "0.0.0.0",
Username: "sa",
Password: "password",
Port: 1433,
},
expectedSuccess: true,
},
}

for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
require.NoError(t, component.ValidateConfig(tc.cfg))
if tc.expectedSuccess {
require.NoError(t, component.ValidateConfig(tc.cfg))
} else {
require.Error(t, component.ValidateConfig(tc.cfg))
}
})
}
}
Expand Down
19 changes: 19 additions & 0 deletions receiver/sqlserverreceiver/config_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

//go:build windows

package sqlserverreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/sqlserverreceiver"

import "fmt"

func (cfg *Config) validateInstanceAndComputerName() error {
if cfg.InstanceName != "" && cfg.ComputerName == "" {
return fmt.Errorf("'instance_name' may not be specified without 'computer_name'")
}
if cfg.InstanceName == "" && cfg.ComputerName != "" {
return fmt.Errorf("'computer_name' may not be specified without 'instance_name'")
}

return nil
}
79 changes: 79 additions & 0 deletions receiver/sqlserverreceiver/config_windows_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

//go:build windows

package sqlserverreceiver

import (
"testing"

"github.com/stretchr/testify/require"
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/receiver/scraperhelper"

"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/sqlserverreceiver/internal/metadata"
)

func TestValidateWindows(t *testing.T) {
testCases := []struct {
desc string
cfg *Config
expectedSuccess bool
}{
{
desc: "valid config",
cfg: &Config{
MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig(),
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
},
expectedSuccess: true,
}, {
desc: "valid config with no metric settings",
cfg: &Config{
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
},
expectedSuccess: true,
},
{
desc: "default config is valid",
cfg: createDefaultConfig().(*Config),
expectedSuccess: true,
},
{
desc: "invalid config with computer_name but not instance_name",
cfg: &Config{
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
ComputerName: "ComputerName",
},
expectedSuccess: false,
},
{
desc: "invalid config with instance_name but not computer_name",
cfg: &Config{
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
InstanceName: "InstanceName",
},
expectedSuccess: false,
},
{
desc: "valid config with both names set",
cfg: &Config{
ControllerConfig: scraperhelper.NewDefaultControllerConfig(),
ComputerName: "ComputerName",
InstanceName: "InstanceName",
},
expectedSuccess: true,
},
}

for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
if tc.expectedSuccess {
require.NoError(t, component.ValidateConfig(tc.cfg))
} else {
require.Error(t, component.ValidateConfig(tc.cfg))
}
})
}
}
6 changes: 6 additions & 0 deletions receiver/sqlserverreceiver/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,9 @@ func createDefaultConfig() component.Config {
MetricsBuilderConfig: metadata.DefaultMetricsBuilderConfig(),
}
}

func directDBConnectionEnabled(config *Config) bool {
return config.Server != "" &&
config.Username != "" &&
string(config.Password) != ""
}
1 change: 1 addition & 0 deletions receiver/sqlserverreceiver/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/winperfcounters v0.98.0
github.com/stretchr/testify v1.9.0
go.opentelemetry.io/collector/component v0.98.1-0.20240412014414-62f589864e3d
go.opentelemetry.io/collector/config/configopaque v1.5.1-0.20240412014414-62f589864e3d
go.opentelemetry.io/collector/confmap v0.98.1-0.20240412014414-62f589864e3d
go.opentelemetry.io/collector/consumer v0.98.1-0.20240412014414-62f589864e3d
go.opentelemetry.io/collector/pdata v1.5.1-0.20240412014414-62f589864e3d
Expand Down
2 changes: 2 additions & 0 deletions receiver/sqlserverreceiver/go.sum

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

0 comments on commit a980e8e

Please sign in to comment.