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

Fix an issue with the static to flow converter for blackbox exporter … #5476

Merged
merged 1 commit into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ Main (unreleased)

- Fix the handling of the `--cluster.join-addresses` flag causing an invalid
comparison with the mutually-exclusive `--cluster.discover-peers`. (@tpaschalis)

- Fix an issue with the static to flow converter for blackbox exporter modules
config not being included in the river output. (@erikbaranowski)

### Enhancements

Expand Down
7 changes: 4 additions & 3 deletions component/prometheus/exporter/blackbox/blackbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/grafana/agent/component/prometheus/exporter"
"github.com/grafana/agent/pkg/integrations"
"github.com/grafana/agent/pkg/integrations/blackbox_exporter"
"github.com/grafana/agent/pkg/util"
"github.com/grafana/river/rivertypes"
)

Expand Down Expand Up @@ -92,7 +93,6 @@ type Arguments struct {
Config rivertypes.OptionalSecret `river:"config,attr,optional"`
Targets TargetBlock `river:"target,block"`
ProbeTimeoutOffset time.Duration `river:"probe_timeout_offset,attr,optional"`
ConfigStruct blackbox_config.Config
}

// SetToDefault implements river.Defaulter.
Expand All @@ -106,7 +106,8 @@ func (a *Arguments) Validate() error {
return errors.New("config and config_file are mutually exclusive")
}

err := yaml.UnmarshalStrict([]byte(a.Config.Value), &a.ConfigStruct)
var blackboxConfig blackbox_config.Config
err := yaml.UnmarshalStrict([]byte(a.Config.Value), &blackboxConfig)
if err != nil {
return fmt.Errorf("invalid backbox_exporter config: %s", err)
}
Expand All @@ -118,7 +119,7 @@ func (a *Arguments) Validate() error {
func (a *Arguments) Convert() *blackbox_exporter.Config {
return &blackbox_exporter.Config{
BlackboxConfigFile: a.ConfigFile,
BlackboxConfig: a.ConfigStruct,
BlackboxConfig: util.RawYAML(a.Config.Value),
BlackboxTargets: a.Targets.Convert(),
ProbeTimeoutOffset: a.ProbeTimeoutOffset.Seconds(),
}
Expand Down
43 changes: 41 additions & 2 deletions component/prometheus/exporter/blackbox/blackbox_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import (
"github.com/grafana/agent/component"
"github.com/grafana/agent/component/discovery"
"github.com/grafana/river"
blackbox_config "github.com/prometheus/blackbox_exporter/config"
"github.com/prometheus/common/model"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v2"
)

func TestUnmarshalRiver(t *testing.T) {
Expand Down Expand Up @@ -56,8 +58,11 @@ func TestUnmarshalRiverWithInlineConfig(t *testing.T) {
err := river.Unmarshal([]byte(riverCfg), &args)
require.NoError(t, err)
require.Equal(t, "", args.ConfigFile)
require.Equal(t, args.ConfigStruct.Modules["http_2xx"].Prober, "http")
require.Equal(t, args.ConfigStruct.Modules["http_2xx"].Timeout, 5*time.Second)
var blackboxConfig blackbox_config.Config
err = yaml.UnmarshalStrict([]byte(args.Config.Value), &blackboxConfig)
require.NoError(t, err)
require.Equal(t, blackboxConfig.Modules["http_2xx"].Prober, "http")
require.Equal(t, blackboxConfig.Modules["http_2xx"].Timeout, 5*time.Second)
require.Equal(t, 2, len(args.Targets))
require.Equal(t, 500*time.Millisecond, args.ProbeTimeoutOffset)
require.Contains(t, "target_a", args.Targets[0].Name)
Expand All @@ -67,6 +72,40 @@ func TestUnmarshalRiverWithInlineConfig(t *testing.T) {
require.Contains(t, "http://grafana.com", args.Targets[1].Target)
require.Contains(t, "http_2xx", args.Targets[1].Module)
}

func TestUnmarshalRiverWithInlineConfigYaml(t *testing.T) {
riverCfg := `
config = "modules:\n http_2xx:\n prober: http\n timeout: 5s\n"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to include this similar test since it validates and demonstrates the traditional yaml format in use for this argument.


target "target_a" {
address = "http://example.com"
module = "http_2xx"
}
target "target_b" {
address = "http://grafana.com"
module = "http_2xx"
}
probe_timeout_offset = "0.5s"
`
var args Arguments
err := river.Unmarshal([]byte(riverCfg), &args)
require.NoError(t, err)
require.Equal(t, "", args.ConfigFile)
var blackboxConfig blackbox_config.Config
err = yaml.UnmarshalStrict([]byte(args.Config.Value), &blackboxConfig)
require.NoError(t, err)
require.Equal(t, blackboxConfig.Modules["http_2xx"].Prober, "http")
require.Equal(t, blackboxConfig.Modules["http_2xx"].Timeout, 5*time.Second)
require.Equal(t, 2, len(args.Targets))
require.Equal(t, 500*time.Millisecond, args.ProbeTimeoutOffset)
require.Contains(t, "target_a", args.Targets[0].Name)
require.Contains(t, "http://example.com", args.Targets[0].Target)
require.Contains(t, "http_2xx", args.Targets[0].Module)
require.Contains(t, "target_b", args.Targets[1].Name)
require.Contains(t, "http://grafana.com", args.Targets[1].Target)
require.Contains(t, "http_2xx", args.Targets[1].Module)
}

func TestUnmarshalRiverWithInvalidInlineConfig(t *testing.T) {
var tests = []struct {
testname string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ func (b *IntegrationsV1ConfigBuilder) appendBlackboxExporter(config *blackbox_ex

func toBlackboxExporter(config *blackbox_exporter.Config) *blackbox.Arguments {
return &blackbox.Arguments{
ConfigFile: config.BlackboxConfigFile,
Config: rivertypes.OptionalSecret{},
ConfigFile: config.BlackboxConfigFile,
Config: rivertypes.OptionalSecret{
IsSecret: false,
Value: string(config.BlackboxConfig),
},
Targets: toBlackboxTargets(config.BlackboxTargets),
ProbeTimeoutOffset: time.Duration(config.ProbeTimeoutOffset),
ConfigStruct: config.BlackboxConfig,
}
}

Expand Down
2 changes: 2 additions & 0 deletions converter/internal/staticconvert/testdata/integrations.river
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ prometheus.remote_write "integrations" {
}

prometheus.exporter.blackbox "integrations_blackbox" {
config = "modules:\n http_2xx:\n prober: http\n timeout: 5s\n http:\n method: POST\n headers:\n Content-Type: application/json\n body: '{}'\n preferred_ip_protocol: ip4\n"

target "example" {
address = "http://example.com"
module = "http_2xx"
Expand Down
26 changes: 20 additions & 6 deletions pkg/integrations/blackbox_exporter/blackbox_exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import (
"github.com/go-kit/log"
"github.com/grafana/agent/pkg/integrations"
"github.com/grafana/agent/pkg/integrations/config"
"github.com/grafana/agent/pkg/util"
blackbox_config "github.com/prometheus/blackbox_exporter/config"
"github.com/prometheus/blackbox_exporter/prober"
"github.com/prometheus/client_golang/prometheus"
"gopkg.in/yaml.v3"
)

// DefaultConfig holds the default settings for the blackbox_exporter integration.
Expand Down Expand Up @@ -39,18 +41,24 @@ type BlackboxTarget struct {

// Config configures the Blackbox integration.
type Config struct {
BlackboxConfigFile string `yaml:"config_file,omitempty"`
BlackboxTargets []BlackboxTarget `yaml:"blackbox_targets"`
BlackboxConfig blackbox_config.Config `yaml:"blackbox_config,omitempty"`
ProbeTimeoutOffset float64 `yaml:"probe_timeout_offset,omitempty"`
BlackboxConfigFile string `yaml:"config_file,omitempty"`
BlackboxTargets []BlackboxTarget `yaml:"blackbox_targets"`
BlackboxConfig util.RawYAML `yaml:"blackbox_config,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an aside:

This would normally be the kind of thing which would be a breaking change to the code API. To me, that's re-enforcing the idea of putting everything in internal/ for 1.0 until we're ready to pick a subset of packages to expose.

ProbeTimeoutOffset float64 `yaml:"probe_timeout_offset,omitempty"`
}

// UnmarshalYAML implements yaml.Unmarshaler for Config.
func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error {
*c = DefaultConfig

type plain Config
return unmarshal((*plain)(c))
err := unmarshal((*plain)(c))
if err != nil {
return err
}

var blackbox_config blackbox_config.Config
return yaml.Unmarshal(c.BlackboxConfig, &blackbox_config)
}

// Name returns the name of the integration.
Expand Down Expand Up @@ -96,7 +104,13 @@ func LoadBlackboxConfig(log log.Logger, configFile string, targets []BlackboxTar

// New creates a new blackbox_exporter integration
func New(log log.Logger, c *Config) (integrations.Integration, error) {
modules, err := LoadBlackboxConfig(log, c.BlackboxConfigFile, c.BlackboxTargets, &c.BlackboxConfig)
var blackbox_config blackbox_config.Config
err := yaml.Unmarshal(c.BlackboxConfig, &blackbox_config)
if err != nil {
return nil, err
}

modules, err := LoadBlackboxConfig(log, c.BlackboxConfigFile, c.BlackboxTargets, &blackbox_config)
if err != nil {
return nil, err
}
Expand Down