Skip to content
Open
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
34 changes: 21 additions & 13 deletions plugins/inputs/prometheus/target_allocator.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,26 +57,30 @@ func isPodNameAvailable() bool {
}
return true
}
func loadConfigFromFilename(filename string) (*otelpromreceiver.Config, error) {

// loadConfigFromFilename reads and parses the prometheus config file.
// Returns the config, whether a target_allocator section was present, and any error.
func loadConfigFromFilename(filename string) (*otelpromreceiver.Config, bool, error) {
yamlFile, err := os.ReadFile(filename)
if err != nil {
return nil, err
return nil, true, err // can't determine; default to warn
}
var stringMap map[string]interface{}
err = yaml.Unmarshal(yamlFile, &stringMap)
if err != nil {
return nil, err
return nil, true, err // can't determine; default to warn
}
_, hasTA := stringMap["target_allocator"]
componentParser := confmap.NewFromStringMap(stringMap)
if componentParser == nil {
return nil, fmt.Errorf("unable to parse config from filename %s", filename)
return nil, hasTA, fmt.Errorf("unable to parse config from filename %s", filename)
}
var cfg otelpromreceiver.Config
err = componentParser.Unmarshal(&cfg)
if err != nil {
return nil, err
return nil, hasTA, err
}
return &cfg, nil
return &cfg, hasTA, nil
}

func createTargetAllocatorManager(filename string, logger *slog.Logger, logLevel *promslog.AllowedLevel, sm *scrape.Manager, dm *discovery.Manager) *TargetAllocatorManager {
Expand All @@ -92,9 +96,13 @@ func createTargetAllocatorManager(filename string, logger *slog.Logger, logLevel
reloadConfigHandler: nil,
logger: logger,
}
err := tam.loadConfig(filename)
hasTA, err := tam.loadConfig(filename)
if err != nil {
logger.Warn("Could not load config for target allocator from file", "filename", filename, "err", err)
if hasTA {
logger.Warn("Could not load config for target allocator from file", "filename", filename, "err", err)
} else {
logger.Debug("Target allocator not configured; skipping target allocator config load", "filename", filename, "err", err)
}
return &tam
}
if tam.config == nil {
Expand Down Expand Up @@ -142,21 +150,21 @@ func createZapLogger(level *promslog.AllowedLevel) (*zap.Logger, error) {
return zapLogger, err
}

func (tam *TargetAllocatorManager) loadConfig(filename string) error {
config, err := loadConfigFromFilename(filename)
func (tam *TargetAllocatorManager) loadConfig(filename string) (bool, error) {
config, hasTA, err := loadConfigFromFilename(filename)
if err != nil {
return err
return hasTA, err
}
tam.config = config
if tam.config.TargetAllocator == nil {
return nil // no target allocator return
return hasTA, nil // no target allocator return
Comment thread
musa-asad marked this conversation as resolved.
}
//has target allocator
tam.config.TargetAllocator.TLSSetting.CAFile = DefaultTLSCaFilePath
tam.config.TargetAllocator.TLSSetting.CertFile = DefaultTLSCertFilePath
tam.config.TargetAllocator.TLSSetting.KeyFile = DefaultTLSKeyFilePath
tam.config.TargetAllocator.TLSSetting.ReloadInterval = DEFAULT_TLS_RELOAD_INTERVAL_SECONDS
return nil
return hasTA, nil
}
func (tam *TargetAllocatorManager) Run() error {
err := tam.manager.Start(context.Background(), tam.host, tam.sm, tam.dm)
Expand Down
75 changes: 75 additions & 0 deletions plugins/inputs/prometheus/target_allocator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT

package prometheus

import (
"bytes"
"log/slog"
"os"
"path/filepath"
"testing"

"github.com/prometheus/common/promslog"
"github.com/stretchr/testify/assert"
)

// newCapturingLogger returns a logger that captures all output for test assertions.
func newCapturingLogger() (*slog.Logger, *bytes.Buffer) {
buf := &bytes.Buffer{}
logger := slog.New(slog.NewTextHandler(buf, &slog.HandlerOptions{Level: slog.LevelDebug}))
return logger, buf
}

func infoLevel() *promslog.AllowedLevel {
lvl := &promslog.AllowedLevel{}
_ = lvl.Set("info")
return lvl
}

// TestCreateTargetAllocatorManager_NoTASection_NoWarn verifies no Warn is logged for a non-TA config.
func TestCreateTargetAllocatorManager_NoTASection_NoWarn(t *testing.T) {
logger, buf := newCapturingLogger()

tam := createTargetAllocatorManager("testdata/base-k8.yaml", logger, infoLevel(), nil, nil)

assert.False(t, tam.enabled, "TA must be disabled")

out := buf.String()
assert.NotContains(t, out, "level=WARN", "no Warn expected")
assert.NotContains(t, out, "Could not load config for target allocator",
"spurious TA warning must not appear")

assert.Contains(t, out, "level=DEBUG")
assert.Contains(t, out, "Target allocator not configured")
}

// TestCreateTargetAllocatorManager_MalformedTASection_Warns verifies a genuine TA config error still warns.
func TestCreateTargetAllocatorManager_MalformedTASection_Warns(t *testing.T) {
dir := t.TempDir()
badTA := filepath.Join(dir, "bad-ta.yaml")
// Has target_allocator section but an invalid key that fails strict unmarshal.
content := []byte("target_allocator:\n endpoint: http://target-allocator-service:80\n interval: 30s\nthis_key_is_invalid: true\n")
assert.NoError(t, os.WriteFile(badTA, content, 0o600))

logger, buf := newCapturingLogger()

tam := createTargetAllocatorManager(badTA, logger, infoLevel(), nil, nil)

assert.False(t, tam.enabled, "manager stays disabled")
out := buf.String()
assert.Contains(t, out, "level=WARN", "genuine TA error must still warn")
assert.Contains(t, out, "Could not load config for target allocator")
}

// TestLoadConfigFromFilename_HasTA tests the TA section detection in loadConfigFromFilename.
func TestLoadConfigFromFilename_HasTA(t *testing.T) {
_, hasTA, _ := loadConfigFromFilename("testdata/base-k8.yaml")
assert.False(t, hasTA, "no TA section")

_, hasTA, _ = loadConfigFromFilename("testdata/target_allocator.yaml")
assert.True(t, hasTA, "has TA section")

_, hasTA, _ = loadConfigFromFilename("testdata/does-not-exist.yaml")
assert.True(t, hasTA, "missing file defaults to true (warn)")
}
Loading