diff --git a/.chloggen/feat_ta-cliconfig.yaml b/.chloggen/feat_ta-cliconfig.yaml new file mode 100755 index 0000000000..6d42bb7f14 --- /dev/null +++ b/.chloggen/feat_ta-cliconfig.yaml @@ -0,0 +1,16 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. operator, target allocator, github action) +component: target allocator + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Allow target allocator to be completely configured via the config file + +# One or more tracking issues related to the change +issues: [2129] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/cmd/otel-allocator/config/config.go b/cmd/otel-allocator/config/config.go index 4828722bc1..2db285d4a0 100644 --- a/cmd/otel-allocator/config/config.go +++ b/cmd/otel-allocator/config/config.go @@ -16,11 +16,9 @@ package config import ( "errors" - "flag" "fmt" "io/fs" "os" - "path/filepath" "time" "github.com/go-logr/logr" @@ -31,7 +29,6 @@ import ( "gopkg.in/yaml.v2" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" - "k8s.io/client-go/util/homedir" "k8s.io/klog/v2" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/log/zap" @@ -42,8 +39,12 @@ const DefaultConfigFilePath string = "/conf/targetallocator.yaml" const DefaultCRScrapeInterval model.Duration = model.Duration(time.Second * 30) type Config struct { + ListenAddr string `yaml:"listen_addr,omitempty"` + KubeConfigFilePath string `yaml:"kube_config_file_path,omitempty"` + ClusterConfig *rest.Config `yaml:"-"` + RootLogger logr.Logger `yaml:"-"` LabelSelector map[string]string `yaml:"label_selector,omitempty"` - Config *promconfig.Config `yaml:"config"` + PromConfig *promconfig.Config `yaml:"config"` AllocationStrategy *string `yaml:"allocation_strategy,omitempty"` FilterStrategy *string `yaml:"filter_strategy,omitempty"` PrometheusCR PrometheusCRConfig `yaml:"prometheus_cr,omitempty"` @@ -52,6 +53,7 @@ type Config struct { } type PrometheusCRConfig struct { + Enabled bool `yaml:"enabled,omitempty"` ScrapeInterval model.Duration `yaml:"scrape_interval,omitempty"` } @@ -69,26 +71,45 @@ func (c Config) GetTargetsFilterStrategy() string { return "" } -type PrometheusCRWatcherConfig struct { - Enabled *bool +func LoadFromFile(file string, target *Config) error { + return unmarshal(target, file) } -type CLIConfig struct { - ListenAddr *string - ConfigFilePath *string - ClusterConfig *rest.Config - // KubeConfigFilePath empty if in cluster configuration is in use - KubeConfigFilePath string - RootLogger logr.Logger - PromCRWatcherConf PrometheusCRWatcherConfig -} +func LoadFromCLI(target *Config, flagSet *pflag.FlagSet) error { + var err error + // set the rest of the config attributes based on command-line flag values + target.RootLogger = zap.New(zap.UseFlagOptions(&zapCmdLineOpts)) + klog.SetLogger(target.RootLogger) + ctrl.SetLogger(target.RootLogger) + + target.KubeConfigFilePath, err = getKubeConfigFilePath(flagSet) + if err != nil { + return err + } + clusterConfig, err := clientcmd.BuildConfigFromFlags("", target.KubeConfigFilePath) + if err != nil { + pathError := &fs.PathError{} + if ok := errors.As(err, &pathError); !ok { + return err + } + clusterConfig, err = rest.InClusterConfig() + if err != nil { + return err + } + } + target.ClusterConfig = clusterConfig -func Load(file string) (Config, error) { - cfg := createDefaultConfig() - if err := unmarshal(&cfg, file); err != nil { - return Config{}, err + target.ListenAddr, err = getListenAddr(flagSet) + if err != nil { + return err + } + + target.PrometheusCR.Enabled, err = getPrometheusCREnabled(flagSet) + if err != nil { + return err } - return cfg, nil + + return nil } func unmarshal(cfg *Config, configFile string) error { @@ -103,7 +124,7 @@ func unmarshal(cfg *Config, configFile string) error { return nil } -func createDefaultConfig() Config { +func CreateDefaultConfig() Config { return Config{ PrometheusCR: PrometheusCRConfig{ ScrapeInterval: DefaultCRScrapeInterval, @@ -111,44 +132,39 @@ func createDefaultConfig() Config { } } -func ParseCLI() (CLIConfig, error) { - opts := zap.Options{} - opts.BindFlags(flag.CommandLine) - cLIConf := CLIConfig{ - ListenAddr: pflag.String("listen-addr", ":8080", "The address where this service serves."), - ConfigFilePath: pflag.String("config-file", DefaultConfigFilePath, "The path to the config file."), - PromCRWatcherConf: PrometheusCRWatcherConfig{ - Enabled: pflag.Bool("enable-prometheus-cr-watcher", false, "Enable Prometheus CRs as target sources"), - }, +func Load() (*Config, string, error) { + var err error + + flagSet := getFlagSet(pflag.ExitOnError) + err = flagSet.Parse(os.Args) + if err != nil { + return nil, "", err } - kubeconfigPath := pflag.String("kubeconfig-path", filepath.Join(homedir.HomeDir(), ".kube", "config"), "absolute path to the KubeconfigPath file") - pflag.Parse() - cLIConf.RootLogger = zap.New(zap.UseFlagOptions(&opts)) - klog.SetLogger(cLIConf.RootLogger) - ctrl.SetLogger(cLIConf.RootLogger) + config := CreateDefaultConfig() - clusterConfig, err := clientcmd.BuildConfigFromFlags("", *kubeconfigPath) - cLIConf.KubeConfigFilePath = *kubeconfigPath + // load the config from the config file + configFilePath, err := getConfigFilePath(flagSet) if err != nil { - pathError := &fs.PathError{} - if ok := errors.As(err, &pathError); !ok { - return CLIConfig{}, err - } - clusterConfig, err = rest.InClusterConfig() - if err != nil { - return CLIConfig{}, err - } - cLIConf.KubeConfigFilePath = "" // reset as we use in cluster configuration + return nil, "", err + } + err = LoadFromFile(configFilePath, &config) + if err != nil { + return nil, "", err } - cLIConf.ClusterConfig = clusterConfig - return cLIConf, nil + + err = LoadFromCLI(&config, flagSet) + if err != nil { + return nil, "", err + } + + return &config, configFilePath, nil } // ValidateConfig validates the cli and file configs together. -func ValidateConfig(config *Config, cliConfig *CLIConfig) error { - scrapeConfigsPresent := (config.Config != nil && len(config.Config.ScrapeConfigs) > 0) - if !(*cliConfig.PromCRWatcherConf.Enabled || scrapeConfigsPresent) { +func ValidateConfig(config *Config) error { + scrapeConfigsPresent := (config.PromConfig != nil && len(config.PromConfig.ScrapeConfigs) > 0) + if !(config.PrometheusCR.Enabled || scrapeConfigsPresent) { return fmt.Errorf("at least one scrape config must be defined, or Prometheus CR watching must be enabled") } return nil diff --git a/cmd/otel-allocator/config/config_test.go b/cmd/otel-allocator/config/config_test.go index 91f0d63b70..89f6307d85 100644 --- a/cmd/otel-allocator/config/config_test.go +++ b/cmd/otel-allocator/config/config_test.go @@ -51,7 +51,7 @@ func TestLoad(t *testing.T) { PrometheusCR: PrometheusCRConfig{ ScrapeInterval: model.Duration(time.Second * 60), }, - Config: &promconfig.Config{ + PromConfig: &promconfig.Config{ GlobalConfig: promconfig.GlobalConfig{ ScrapeInterval: model.Duration(60 * time.Second), ScrapeTimeout: model.Duration(10 * time.Second), @@ -99,7 +99,7 @@ func TestLoad(t *testing.T) { args: args{ file: "./testdata/no_config.yaml", }, - want: createDefaultConfig(), + want: CreateDefaultConfig(), wantErr: assert.NoError, }, { @@ -115,7 +115,7 @@ func TestLoad(t *testing.T) { PrometheusCR: PrometheusCRConfig{ ScrapeInterval: DefaultCRScrapeInterval, }, - Config: &promconfig.Config{ + PromConfig: &promconfig.Config{ GlobalConfig: promconfig.GlobalConfig{ ScrapeInterval: model.Duration(60 * time.Second), ScrapeTimeout: model.Duration(10 * time.Second), @@ -163,7 +163,8 @@ func TestLoad(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := Load(tt.args.file) + got := CreateDefaultConfig() + err := LoadFromFile(tt.args.file, &got) if !tt.wantErr(t, err, fmt.Sprintf("Load(%v)", tt.args.file)) { return } @@ -173,45 +174,38 @@ func TestLoad(t *testing.T) { } func TestValidateConfig(t *testing.T) { - enabled := true - disabled := false testCases := []struct { name string - cliConfig CLIConfig fileConfig Config expectedErr error }{ { name: "promCR enabled, no Prometheus config", - cliConfig: CLIConfig{PromCRWatcherConf: PrometheusCRWatcherConfig{Enabled: &enabled}}, - fileConfig: Config{Config: nil}, + fileConfig: Config{PromConfig: nil, PrometheusCR: PrometheusCRConfig{Enabled: true}}, expectedErr: nil, }, { name: "promCR disabled, no Prometheus config", - cliConfig: CLIConfig{PromCRWatcherConf: PrometheusCRWatcherConfig{Enabled: &disabled}}, - fileConfig: Config{Config: nil}, + fileConfig: Config{PromConfig: nil}, expectedErr: fmt.Errorf("at least one scrape config must be defined, or Prometheus CR watching must be enabled"), }, { name: "promCR disabled, Prometheus config present, no scrapeConfigs", - cliConfig: CLIConfig{PromCRWatcherConf: PrometheusCRWatcherConfig{Enabled: &disabled}}, - fileConfig: Config{Config: &promconfig.Config{}}, + fileConfig: Config{PromConfig: &promconfig.Config{}}, expectedErr: fmt.Errorf("at least one scrape config must be defined, or Prometheus CR watching must be enabled"), }, { - name: "promCR disabled, Prometheus config present, scrapeConfigs present", - cliConfig: CLIConfig{PromCRWatcherConf: PrometheusCRWatcherConfig{Enabled: &disabled}}, + name: "promCR disabled, Prometheus config present, scrapeConfigs present", fileConfig: Config{ - Config: &promconfig.Config{ScrapeConfigs: []*promconfig.ScrapeConfig{{}}}, + PromConfig: &promconfig.Config{ScrapeConfigs: []*promconfig.ScrapeConfig{{}}}, }, expectedErr: nil, }, { - name: "promCR enabled, Prometheus config present, scrapeConfigs present", - cliConfig: CLIConfig{PromCRWatcherConf: PrometheusCRWatcherConfig{Enabled: &enabled}}, + name: "promCR enabled, Prometheus config present, scrapeConfigs present", fileConfig: Config{ - Config: &promconfig.Config{ScrapeConfigs: []*promconfig.ScrapeConfig{{}}}, + PromConfig: &promconfig.Config{ScrapeConfigs: []*promconfig.ScrapeConfig{{}}}, + PrometheusCR: PrometheusCRConfig{Enabled: true}, }, expectedErr: nil, }, @@ -219,7 +213,7 @@ func TestValidateConfig(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - err := ValidateConfig(&tc.fileConfig, &tc.cliConfig) + err := ValidateConfig(&tc.fileConfig) assert.Equal(t, tc.expectedErr, err) }) } diff --git a/cmd/otel-allocator/config/flags.go b/cmd/otel-allocator/config/flags.go new file mode 100644 index 0000000000..bb7dbbb344 --- /dev/null +++ b/cmd/otel-allocator/config/flags.go @@ -0,0 +1,64 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package config + +import ( + "flag" + "path/filepath" + + "github.com/spf13/pflag" + "k8s.io/client-go/util/homedir" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +// Flag names. +const ( + targetAllocatorName = "target-allocator" + configFilePathFlagName = "config-file" + listenAddrFlagName = "listen-addr" + prometheusCREnabledFlagName = "enable-prometheus-cr-watcher" + kubeConfigPathFlagName = "kubeconfig-path" +) + +// We can't bind this flag to our FlagSet, so we need to handle it separately. +var zapCmdLineOpts zap.Options + +func getFlagSet(errorHandling pflag.ErrorHandling) *pflag.FlagSet { + flagSet := pflag.NewFlagSet(targetAllocatorName, errorHandling) + flagSet.String(configFilePathFlagName, DefaultConfigFilePath, "The path to the config file.") + flagSet.String(listenAddrFlagName, ":8080", "The address where this service serves.") + flagSet.Bool(prometheusCREnabledFlagName, false, "Enable Prometheus CRs as target sources") + flagSet.String(kubeConfigPathFlagName, filepath.Join(homedir.HomeDir(), ".kube", "config"), "absolute path to the KubeconfigPath file") + zapFlagSet := flag.NewFlagSet("", flag.ErrorHandling(errorHandling)) + zapCmdLineOpts.BindFlags(zapFlagSet) + flagSet.AddGoFlagSet(zapFlagSet) + return flagSet +} + +func getConfigFilePath(flagSet *pflag.FlagSet) (string, error) { + return flagSet.GetString(configFilePathFlagName) +} + +func getKubeConfigFilePath(flagSet *pflag.FlagSet) (string, error) { + return flagSet.GetString(kubeConfigPathFlagName) +} + +func getListenAddr(flagSet *pflag.FlagSet) (string, error) { + return flagSet.GetString(listenAddrFlagName) +} + +func getPrometheusCREnabled(flagSet *pflag.FlagSet) (bool, error) { + return flagSet.GetBool(prometheusCREnabledFlagName) +} diff --git a/cmd/otel-allocator/config/flags_test.go b/cmd/otel-allocator/config/flags_test.go new file mode 100644 index 0000000000..b1bf11b6ce --- /dev/null +++ b/cmd/otel-allocator/config/flags_test.go @@ -0,0 +1,91 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package config + +import ( + "path/filepath" + "testing" + + "github.com/spf13/pflag" + "github.com/stretchr/testify/assert" +) + +func TestGetFlagSet(t *testing.T) { + fs := getFlagSet(pflag.ExitOnError) + + // Check if each flag exists + assert.NotNil(t, fs.Lookup(configFilePathFlagName), "Flag %s not found", configFilePathFlagName) + assert.NotNil(t, fs.Lookup(listenAddrFlagName), "Flag %s not found", listenAddrFlagName) + assert.NotNil(t, fs.Lookup(prometheusCREnabledFlagName), "Flag %s not found", prometheusCREnabledFlagName) + assert.NotNil(t, fs.Lookup(kubeConfigPathFlagName), "Flag %s not found", kubeConfigPathFlagName) +} + +func TestFlagGetters(t *testing.T) { + tests := []struct { + name string + flagArgs []string + expectedValue interface{} + expectedErr bool + getterFunc func(*pflag.FlagSet) (interface{}, error) + }{ + { + name: "GetConfigFilePath", + flagArgs: []string{"--" + configFilePathFlagName, "/path/to/config"}, + expectedValue: "/path/to/config", + getterFunc: func(fs *pflag.FlagSet) (interface{}, error) { return getConfigFilePath(fs) }, + }, + { + name: "GetKubeConfigFilePath", + flagArgs: []string{"--" + kubeConfigPathFlagName, filepath.Join("~", ".kube", "config")}, + expectedValue: filepath.Join("~", ".kube", "config"), + getterFunc: func(fs *pflag.FlagSet) (interface{}, error) { return getKubeConfigFilePath(fs) }, + }, + { + name: "GetListenAddr", + flagArgs: []string{"--" + listenAddrFlagName, ":8081"}, + expectedValue: ":8081", + getterFunc: func(fs *pflag.FlagSet) (interface{}, error) { return getListenAddr(fs) }, + }, + { + name: "GetPrometheusCREnabled", + flagArgs: []string{"--" + prometheusCREnabledFlagName, "true"}, + expectedValue: true, + getterFunc: func(fs *pflag.FlagSet) (interface{}, error) { return getPrometheusCREnabled(fs) }, + }, + { + name: "InvalidFlag", + flagArgs: []string{"--invalid-flag", "value"}, + expectedErr: true, + getterFunc: func(fs *pflag.FlagSet) (interface{}, error) { return getConfigFilePath(fs) }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + fs := getFlagSet(pflag.ContinueOnError) + err := fs.Parse(tt.flagArgs) + + // If an error is expected during parsing, we check it here. + if tt.expectedErr { + assert.Error(t, err) + return + } + + got, err := tt.getterFunc(fs) + assert.NoError(t, err) + assert.Equal(t, tt.expectedValue, got) + }) + } +} diff --git a/cmd/otel-allocator/main.go b/cmd/otel-allocator/main.go index 48f11403b2..0a7cf8dad8 100644 --- a/cmd/otel-allocator/main.go +++ b/cmd/otel-allocator/main.go @@ -16,6 +16,7 @@ package main import ( "context" + "fmt" "os" "os/signal" "syscall" @@ -64,21 +65,18 @@ func main() { interrupts = make(chan os.Signal, 1) errChan = make(chan error) ) - cliConf, err := config.ParseCLI() + cfg, configFilePath, err := config.Load() if err != nil { - setupLog.Error(err, "Failed to parse parameters") + fmt.Printf("Failed to load config: %v", err) os.Exit(1) } - cfg, configLoadErr := config.Load(*cliConf.ConfigFilePath) - if configLoadErr != nil { - setupLog.Error(configLoadErr, "Unable to load configuration") - } + ctrl.SetLogger(cfg.RootLogger) - if validationErr := config.ValidateConfig(&cfg, &cliConf); validationErr != nil { + if validationErr := config.ValidateConfig(cfg); validationErr != nil { setupLog.Error(validationErr, "Invalid configuration") } - cliConf.RootLogger.Info("Starting the Target Allocator") + cfg.RootLogger.Info("Starting the Target Allocator") ctx := context.Background() log := ctrl.Log.WithName("allocator") @@ -88,17 +86,17 @@ func main() { setupLog.Error(err, "Unable to initialize allocation strategy") os.Exit(1) } - srv := server.NewServer(log, allocator, cliConf.ListenAddr) + srv := server.NewServer(log, allocator, cfg.ListenAddr) discoveryCtx, discoveryCancel := context.WithCancel(ctx) discoveryManager = discovery.NewManager(discoveryCtx, gokitlog.NewNopLogger()) targetDiscoverer = target.NewDiscoverer(log, discoveryManager, allocatorPrehook, srv) - collectorWatcher, collectorWatcherErr := collector.NewClient(log, cliConf.ClusterConfig) + collectorWatcher, collectorWatcherErr := collector.NewClient(log, cfg.ClusterConfig) if collectorWatcherErr != nil { setupLog.Error(collectorWatcherErr, "Unable to initialize collector watcher") os.Exit(1) } - fileWatcher, err = allocatorWatcher.NewFileWatcher(setupLog.WithName("file-watcher"), cliConf) + fileWatcher, err = allocatorWatcher.NewFileWatcher(setupLog.WithName("file-watcher"), configFilePath) if err != nil { setupLog.Error(err, "Can't start the file watcher") os.Exit(1) @@ -106,8 +104,8 @@ func main() { signal.Notify(interrupts, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) defer close(interrupts) - if *cliConf.PromCRWatcherConf.Enabled { - promWatcher, err = allocatorWatcher.NewPrometheusCRWatcher(setupLog.WithName("prometheus-cr-watcher"), cfg, cliConf) + if cfg.PrometheusCR.Enabled { + promWatcher, err = allocatorWatcher.NewPrometheusCRWatcher(setupLog.WithName("prometheus-cr-watcher"), *cfg) if err != nil { setupLog.Error(err, "Can't start the prometheus watcher") os.Exit(1) @@ -152,7 +150,7 @@ func main() { runGroup.Add( func() error { // Initial loading of the config file's scrape config - err = targetDiscoverer.ApplyConfig(allocatorWatcher.EventSourceConfigMap, cfg.Config) + err = targetDiscoverer.ApplyConfig(allocatorWatcher.EventSourceConfigMap, cfg.PromConfig) if err != nil { setupLog.Error(err, "Unable to apply initial configuration") return err diff --git a/cmd/otel-allocator/server/bench_test.go b/cmd/otel-allocator/server/bench_test.go index e2b90c1369..8fcea90b0e 100644 --- a/cmd/otel-allocator/server/bench_test.go +++ b/cmd/otel-allocator/server/bench_test.go @@ -54,7 +54,7 @@ func BenchmarkServerTargetsHandler(b *testing.B) { listenAddr := ":8080" a.SetCollectors(cols) a.SetTargets(targets) - s := NewServer(logger, a, &listenAddr) + s := NewServer(logger, a, listenAddr) b.Run(fmt.Sprintf("%s_num_cols_%d_num_jobs_%d", allocatorName, v.numCollectors, v.numJobs), func(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { diff --git a/cmd/otel-allocator/server/server.go b/cmd/otel-allocator/server/server.go index 8351a85d3e..c9c93951d7 100644 --- a/cmd/otel-allocator/server/server.go +++ b/cmd/otel-allocator/server/server.go @@ -71,7 +71,7 @@ type Server struct { scrapeConfigResponse []byte } -func NewServer(log logr.Logger, allocator allocation.Allocator, listenAddr *string) *Server { +func NewServer(log logr.Logger, allocator allocation.Allocator, listenAddr string) *Server { s := &Server{ logger: log, allocator: allocator, @@ -90,7 +90,7 @@ func NewServer(log logr.Logger, allocator allocation.Allocator, listenAddr *stri router.GET("/metrics", gin.WrapH(promhttp.Handler())) registerPprof(router.Group("/debug/pprof/")) - s.server = &http.Server{Addr: *listenAddr, Handler: router, ReadHeaderTimeout: 90 * time.Second} + s.server = &http.Server{Addr: listenAddr, Handler: router, ReadHeaderTimeout: 90 * time.Second} return s } diff --git a/cmd/otel-allocator/server/server_test.go b/cmd/otel-allocator/server/server_test.go index c58f5dc6b4..975df83acf 100644 --- a/cmd/otel-allocator/server/server_test.go +++ b/cmd/otel-allocator/server/server_test.go @@ -154,7 +154,7 @@ func TestServer_TargetsHandler(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { listenAddr := ":8080" - s := NewServer(logger, tt.args.allocator, &listenAddr) + s := NewServer(logger, tt.args.allocator, listenAddr) tt.args.allocator.SetCollectors(map[string]*allocation.Collector{"test-collector": {Name: "test-collector"}}) tt.args.allocator.SetTargets(tt.args.cMap) request := httptest.NewRequest("GET", fmt.Sprintf("/jobs/%s/targets?collector_id=%s", tt.args.job, tt.args.collector), nil) @@ -445,7 +445,7 @@ func TestServer_ScrapeConfigsHandler(t *testing.T) { for _, tc := range tests { t.Run(tc.description, func(t *testing.T) { listenAddr := ":8080" - s := NewServer(logger, nil, &listenAddr) + s := NewServer(logger, nil, listenAddr) assert.NoError(t, s.UpdateScrapeConfigResponse(tc.scrapeConfigs)) request := httptest.NewRequest("GET", "/scrape_configs", nil) @@ -518,7 +518,7 @@ func TestServer_JobHandler(t *testing.T) { t.Run(tc.description, func(t *testing.T) { listenAddr := ":8080" a := &mockAllocator{targetItems: tc.targetItems} - s := NewServer(logger, a, &listenAddr) + s := NewServer(logger, a, listenAddr) request := httptest.NewRequest("GET", "/jobs", nil) w := httptest.NewRecorder() diff --git a/cmd/otel-allocator/target/discovery_test.go b/cmd/otel-allocator/target/discovery_test.go index 49bfaa471d..25a44b6411 100644 --- a/cmd/otel-allocator/target/discovery_test.go +++ b/cmd/otel-allocator/target/discovery_test.go @@ -83,10 +83,11 @@ func TestDiscovery(t *testing.T) { }() for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - cfg, err := config.Load(tt.args.file) + cfg := config.CreateDefaultConfig() + err := config.LoadFromFile(tt.args.file, &cfg) assert.NoError(t, err) - assert.True(t, len(cfg.Config.ScrapeConfigs) > 0) - err = manager.ApplyConfig(allocatorWatcher.EventSourcePrometheusCR, cfg.Config) + assert.True(t, len(cfg.PromConfig.ScrapeConfigs) > 0) + err = manager.ApplyConfig(allocatorWatcher.EventSourcePrometheusCR, cfg.PromConfig) assert.NoError(t, err) gotTargets := <-results @@ -96,7 +97,7 @@ func TestDiscovery(t *testing.T) { // check the updated scrape configs expectedScrapeConfigs := map[string]*promconfig.ScrapeConfig{} - for _, scrapeConfig := range cfg.Config.ScrapeConfigs { + for _, scrapeConfig := range cfg.PromConfig.ScrapeConfigs { expectedScrapeConfigs[scrapeConfig.JobName] = scrapeConfig } assert.Equal(t, expectedScrapeConfigs, scu.mockCfg) diff --git a/cmd/otel-allocator/watcher/file.go b/cmd/otel-allocator/watcher/file.go index 95b5cfaaa1..a6bbd15fd0 100644 --- a/cmd/otel-allocator/watcher/file.go +++ b/cmd/otel-allocator/watcher/file.go @@ -34,7 +34,7 @@ type FileWatcher struct { closer chan bool } -func NewFileWatcher(logger logr.Logger, config config.CLIConfig) (*FileWatcher, error) { +func NewFileWatcher(logger logr.Logger, configFilePath string) (*FileWatcher, error) { fileWatcher, err := fsnotify.NewWatcher() if err != nil { logger.Error(err, "Can't start the watcher") @@ -43,19 +43,20 @@ func NewFileWatcher(logger logr.Logger, config config.CLIConfig) (*FileWatcher, return &FileWatcher{ logger: logger, - configFilePath: *config.ConfigFilePath, + configFilePath: configFilePath, watcher: fileWatcher, closer: make(chan bool), }, nil } func (f *FileWatcher) LoadConfig(_ context.Context) (*promconfig.Config, error) { - cfg, err := config.Load(f.configFilePath) + cfg := config.CreateDefaultConfig() + err := config.LoadFromFile(f.configFilePath, &cfg) if err != nil { f.logger.Error(err, "Unable to load configuration") return nil, err } - return cfg.Config, nil + return cfg.PromConfig, nil } func (f *FileWatcher) Watch(upstreamEvents chan Event, upstreamErrors chan error) error { diff --git a/cmd/otel-allocator/watcher/promOperator.go b/cmd/otel-allocator/watcher/promOperator.go index 3df39e095b..2eb91fe7a9 100644 --- a/cmd/otel-allocator/watcher/promOperator.go +++ b/cmd/otel-allocator/watcher/promOperator.go @@ -37,13 +37,13 @@ import ( allocatorconfig "github.com/open-telemetry/opentelemetry-operator/cmd/otel-allocator/config" ) -func NewPrometheusCRWatcher(logger logr.Logger, cfg allocatorconfig.Config, cliConfig allocatorconfig.CLIConfig) (*PrometheusCRWatcher, error) { - mClient, err := monitoringclient.NewForConfig(cliConfig.ClusterConfig) +func NewPrometheusCRWatcher(logger logr.Logger, cfg allocatorconfig.Config) (*PrometheusCRWatcher, error) { + mClient, err := monitoringclient.NewForConfig(cfg.ClusterConfig) if err != nil { return nil, err } - clientset, err := kubernetes.NewForConfig(cliConfig.ClusterConfig) + clientset, err := kubernetes.NewForConfig(cfg.ClusterConfig) if err != nil { return nil, err } @@ -80,7 +80,7 @@ func NewPrometheusCRWatcher(logger logr.Logger, cfg allocatorconfig.Config, cliC informers: monitoringInformers, stopChannel: make(chan struct{}), configGenerator: generator, - kubeConfigPath: cliConfig.KubeConfigFilePath, + kubeConfigPath: cfg.KubeConfigFilePath, serviceMonitorSelector: servMonSelector, podMonitorSelector: podMonSelector, }, nil