Skip to content

Commit ffce405

Browse files
committed
[target allocator] Allow setting collector namespace via the config file
Make this namespace part of the config and only read the environment variable during config loading.
1 parent 73dd7b3 commit ffce405

11 files changed

+80
-13
lines changed
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
2+
change_type: enhancement
3+
4+
# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action)
5+
component: target allocator
6+
7+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
8+
note: Allow setting the collector namespace via the config file
9+
10+
# One or more tracking issues related to the change
11+
issues: [3782]
12+
13+
# (Optional) One or more lines of additional information to render under the primary note.
14+
# These lines will be padded with 2 spaces and then inserted directly into the document.
15+
# Use pipe (|) for multiline entries.
16+
subtext:

cmd/otel-allocator/internal/collector/collector.go

+6-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
package collector
55

66
import (
7-
"os"
87
"time"
98

109
"github.com/go-logr/logr"
@@ -25,7 +24,6 @@ const (
2524
)
2625

2726
var (
28-
ns = os.Getenv("OTELCOL_NAMESPACE")
2927
collectorsDiscovered = promauto.NewGauge(prometheus.GaugeOpts{
3028
Name: "opentelemetry_allocator_collectors_discovered",
3129
Help: "Number of collectors discovered.",
@@ -53,7 +51,11 @@ func NewCollectorWatcher(logger logr.Logger, kubeConfig *rest.Config) (*Watcher,
5351
}, nil
5452
}
5553

56-
func (k *Watcher) Watch(labelSelector *metav1.LabelSelector, fn func(collectors map[string]*allocation.Collector)) error {
54+
func (k *Watcher) Watch(
55+
collectorNamespace string,
56+
labelSelector *metav1.LabelSelector,
57+
fn func(collectors map[string]*allocation.Collector),
58+
) error {
5759
selector, err := metav1.LabelSelectorAsSelector(labelSelector)
5860
if err != nil {
5961
return err
@@ -65,7 +67,7 @@ func (k *Watcher) Watch(labelSelector *metav1.LabelSelector, fn func(collectors
6567
informerFactory := informers.NewSharedInformerFactoryWithOptions(
6668
k.k8sClient,
6769
time.Second*30,
68-
informers.WithNamespace(ns),
70+
informers.WithNamespace(collectorNamespace),
6971
informers.WithTweakListOptions(listOptionsFunc))
7072
informer := informerFactory.Core().V1().Pods().Informer()
7173

cmd/otel-allocator/internal/collector/collector_test.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ func pod(name string) *v1.Pod {
5353
}
5454

5555
func Test_runWatch(t *testing.T) {
56+
namespace := "test-ns"
5657
type args struct {
5758
kubeFn func(t *testing.T, podWatcher Watcher)
5859
collectorMap map[string]*allocation.Collector
@@ -68,7 +69,7 @@ func Test_runWatch(t *testing.T) {
6869
kubeFn: func(t *testing.T, podWatcher Watcher) {
6970
for _, k := range []string{"test-pod1", "test-pod2", "test-pod3"} {
7071
p := pod(k)
71-
_, err := podWatcher.k8sClient.CoreV1().Pods("test-ns").Create(context.Background(), p, metav1.CreateOptions{})
72+
_, err := podWatcher.k8sClient.CoreV1().Pods(namespace).Create(context.Background(), p, metav1.CreateOptions{})
7273
assert.NoError(t, err)
7374
}
7475
},
@@ -94,7 +95,7 @@ func Test_runWatch(t *testing.T) {
9495
args: args{
9596
kubeFn: func(t *testing.T, podWatcher Watcher) {
9697
for _, k := range []string{"test-pod2", "test-pod3"} {
97-
err := podWatcher.k8sClient.CoreV1().Pods("test-ns").Delete(context.Background(), k, metav1.DeleteOptions{})
98+
err := podWatcher.k8sClient.CoreV1().Pods(namespace).Delete(context.Background(), k, metav1.DeleteOptions{})
9899
assert.NoError(t, err)
99100
}
100101
},
@@ -135,7 +136,7 @@ func Test_runWatch(t *testing.T) {
135136
assert.NoError(t, err)
136137
}
137138
go func(podWatcher Watcher) {
138-
err := podWatcher.Watch(&labelSelector, func(colMap map[string]*allocation.Collector) {
139+
err := podWatcher.Watch(namespace, &labelSelector, func(colMap map[string]*allocation.Collector) {
139140
mapMutex.Lock()
140141
defer mapMutex.Unlock()
141142
actual = colMap
@@ -165,7 +166,7 @@ func Test_closeChannel(t *testing.T) {
165166

166167
go func(podWatcher Watcher) {
167168
defer wg.Done()
168-
err := podWatcher.Watch(&labelSelector, func(colMap map[string]*allocation.Collector) {})
169+
err := podWatcher.Watch("default", &labelSelector, func(colMap map[string]*allocation.Collector) {})
169170
require.NoError(t, err)
170171
}(podWatcher)
171172

cmd/otel-allocator/internal/config/config.go

+15
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ type Config struct {
4242
ClusterConfig *rest.Config `yaml:"-"`
4343
RootLogger logr.Logger `yaml:"-"`
4444
CollectorSelector *metav1.LabelSelector `yaml:"collector_selector,omitempty"`
45+
CollectorNamespace string `yaml:"collector_namespace,omitempty"`
4546
PromConfig *promconfig.Config `yaml:"config"`
4647
AllocationStrategy string `yaml:"allocation_strategy,omitempty"`
4748
AllocationFallbackStrategy string `yaml:"allocation_fallback_strategy,omitempty"`
@@ -239,6 +240,12 @@ func LoadFromCLI(target *Config, flagSet *pflag.FlagSet) error {
239240
return nil
240241
}
241242

243+
// LoadFromEnv loads configuration from environment variables.
244+
func LoadFromEnv(target *Config) error {
245+
target.CollectorNamespace = os.Getenv("OTELCOL_NAMESPACE")
246+
return nil
247+
}
248+
242249
// unmarshal decodes the contents of the configFile into the cfg argument, using a
243250
// mapstructure decoder with the following notable behaviors.
244251
// Decodes time.Duration from strings (see StringToModelDurationHookFunc).
@@ -309,6 +316,11 @@ func Load() (*Config, error) {
309316
return nil, err
310317
}
311318

319+
err = LoadFromEnv(&config)
320+
if err != nil {
321+
return nil, err
322+
}
323+
312324
err = LoadFromCLI(&config, flagSet)
313325
if err != nil {
314326
return nil, err
@@ -323,6 +335,9 @@ func ValidateConfig(config *Config) error {
323335
if !(config.PrometheusCR.Enabled || scrapeConfigsPresent) {
324336
return fmt.Errorf("at least one scrape config must be defined, or Prometheus CR watching must be enabled")
325337
}
338+
if config.CollectorNamespace == "" {
339+
return fmt.Errorf("collector namespace must be set")
340+
}
326341
return nil
327342
}
328343

cmd/otel-allocator/internal/config/config_test.go

+32-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package config
55

66
import (
77
"fmt"
8+
"os"
89
"testing"
910
"time"
1011

@@ -14,6 +15,7 @@ import (
1415
"github.com/prometheus/prometheus/discovery"
1516
"github.com/prometheus/prometheus/discovery/file"
1617
"github.com/stretchr/testify/assert"
18+
"github.com/stretchr/testify/require"
1719
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1820
)
1921

@@ -40,6 +42,7 @@ func TestLoad(t *testing.T) {
4042
},
4143
want: Config{
4244
AllocationStrategy: DefaultAllocationStrategy,
45+
CollectorNamespace: "default",
4346
CollectorSelector: &metav1.LabelSelector{
4447
MatchLabels: map[string]string{
4548
"app.kubernetes.io/instance": "default.test",
@@ -120,6 +123,7 @@ func TestLoad(t *testing.T) {
120123
},
121124
want: Config{
122125
AllocationStrategy: DefaultAllocationStrategy,
126+
CollectorNamespace: "default",
123127
CollectorSelector: &metav1.LabelSelector{
124128
MatchLabels: map[string]string{
125129
"app.kubernetes.io/instance": "default.test",
@@ -190,6 +194,7 @@ func TestLoad(t *testing.T) {
190194
},
191195
want: Config{
192196
AllocationStrategy: DefaultAllocationStrategy,
197+
CollectorNamespace: "default",
193198
CollectorSelector: &metav1.LabelSelector{
194199
MatchLabels: map[string]string{
195200
"app.kubernetes.io/instance": "default.test",
@@ -260,6 +265,7 @@ func TestLoad(t *testing.T) {
260265
},
261266
want: Config{
262267
AllocationStrategy: DefaultAllocationStrategy,
268+
CollectorNamespace: "default",
263269
CollectorSelector: &metav1.LabelSelector{
264270
MatchExpressions: []metav1.LabelSelectorRequirement{
265271
{
@@ -354,6 +360,7 @@ func TestLoad(t *testing.T) {
354360
},
355361
want: Config{
356362
AllocationStrategy: DefaultAllocationStrategy,
363+
CollectorNamespace: "default",
357364
CollectorSelector: &metav1.LabelSelector{
358365
MatchExpressions: []metav1.LabelSelectorRequirement{
359366
{
@@ -454,15 +461,34 @@ func TestLoad(t *testing.T) {
454461
}
455462
}
456463

464+
func TestLoadFromEnv(t *testing.T) {
465+
current := os.Getenv("OTELCOL_NAMESPACE")
466+
t.Cleanup(func() {
467+
err := os.Setenv("OTELCOL_NAMESPACE", current)
468+
assert.NoError(t, err)
469+
})
470+
namespace := "default"
471+
os.Setenv("OTELCOL_NAMESPACE", namespace)
472+
cfg := &Config{}
473+
err := LoadFromEnv(cfg)
474+
require.NoError(t, err)
475+
assert.Equal(t, namespace, cfg.CollectorNamespace)
476+
}
477+
457478
func TestValidateConfig(t *testing.T) {
458479
testCases := []struct {
459480
name string
460481
fileConfig Config
461482
expectedErr error
462483
}{
484+
{
485+
name: "no namespace",
486+
fileConfig: Config{PrometheusCR: PrometheusCRConfig{Enabled: true}},
487+
expectedErr: fmt.Errorf("collector namespace must be set"),
488+
},
463489
{
464490
name: "promCR enabled, no Prometheus config",
465-
fileConfig: Config{PromConfig: nil, PrometheusCR: PrometheusCRConfig{Enabled: true}},
491+
fileConfig: Config{PromConfig: nil, PrometheusCR: PrometheusCRConfig{Enabled: true}, CollectorNamespace: "default"},
466492
expectedErr: nil,
467493
},
468494
{
@@ -478,15 +504,17 @@ func TestValidateConfig(t *testing.T) {
478504
{
479505
name: "promCR disabled, Prometheus config present, scrapeConfigs present",
480506
fileConfig: Config{
481-
PromConfig: &promconfig.Config{ScrapeConfigs: []*promconfig.ScrapeConfig{{}}},
507+
PromConfig: &promconfig.Config{ScrapeConfigs: []*promconfig.ScrapeConfig{{}}},
508+
CollectorNamespace: "default",
482509
},
483510
expectedErr: nil,
484511
},
485512
{
486513
name: "promCR enabled, Prometheus config present, scrapeConfigs present",
487514
fileConfig: Config{
488-
PromConfig: &promconfig.Config{ScrapeConfigs: []*promconfig.ScrapeConfig{{}}},
489-
PrometheusCR: PrometheusCRConfig{Enabled: true},
515+
PromConfig: &promconfig.Config{ScrapeConfigs: []*promconfig.ScrapeConfig{{}}},
516+
PrometheusCR: PrometheusCRConfig{Enabled: true},
517+
CollectorNamespace: "default",
490518
},
491519
expectedErr: nil,
492520
},

cmd/otel-allocator/internal/config/testdata/config_test.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
collector_namespace: default
12
collector_selector:
23
matchlabels:
34
app.kubernetes.io/instance: default.test

cmd/otel-allocator/internal/config/testdata/pod_service_selector_camelcase_expressions_test.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
collector_namespace: default
12
collector_selector:
23
matchExpressions:
34
- key: "app.kubernetes.io/instance"

cmd/otel-allocator/internal/config/testdata/pod_service_selector_camelcase_test.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
collector_namespace: default
12
collector_selector:
23
matchLabels:
34
app.kubernetes.io/instance: default.test

cmd/otel-allocator/internal/config/testdata/pod_service_selector_expressions_test.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
collector_namespace: default
12
collector_selector:
23
matchexpressions:
34
- key: "app.kubernetes.io/instance"

cmd/otel-allocator/internal/config/testdata/pod_service_selector_test.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
collector_namespace: default
12
collector_selector:
23
matchlabels:
34
app.kubernetes.io/instance: default.test

cmd/otel-allocator/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ func main() {
168168
})
169169
runGroup.Add(
170170
func() error {
171-
err := collectorWatcher.Watch(cfg.CollectorSelector, allocator.SetCollectors)
171+
err := collectorWatcher.Watch(cfg.CollectorNamespace, cfg.CollectorSelector, allocator.SetCollectors)
172172
setupLog.Info("Collector watcher exited")
173173
return err
174174
},

0 commit comments

Comments
 (0)