Skip to content

Commit 03b4bd5

Browse files
authored
Propagate global scrape protocols by allowing for global config setting (open-telemetry#3161)
* allow for global config setting for target allocator * allow for global config setting for target allocator * fix e2e test * reset * should be in data * fix test namespace for instance * working test * link to prom docs
1 parent d46833a commit 03b4bd5

11 files changed

+178
-6
lines changed
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: introduces the global field in the TA config to allow for setting scrape protocols
9+
10+
# One or more tracking issues related to the change
11+
issues: [3160]
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:

apis/v1alpha1/targetallocator_types.go

+3
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ type TargetAllocatorSpec struct {
7373
// +optional
7474
// +kubebuilder:default:=relabel-config
7575
FilterStrategy v1beta1.TargetAllocatorFilterStrategy `json:"filterStrategy,omitempty"`
76+
// GlobalConfig configures the global configuration for Prometheus
77+
// For more info, see https://prometheus.io/docs/prometheus/latest/configuration/configuration/#configuration-file.
78+
GlobalConfig v1beta1.AnyConfig `json:"global,omitempty"`
7679
// ScrapeConfigs define static Prometheus scrape configurations for the target allocator.
7780
// To use dynamic configurations from ServiceMonitors and PodMonitors, see the PrometheusCR section.
7881
// For the exact format, see https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config.

apis/v1alpha1/zz_generated.deepcopy.go

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/opentelemetry.io_targetallocators.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -1248,6 +1248,8 @@ spec:
12481248
- ""
12491249
- relabel-config
12501250
type: string
1251+
global:
1252+
type: object
12511253
hostNetwork:
12521254
type: boolean
12531255
image:

internal/manifests/collector/targetallocator.go

+24
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package collector
1616

1717
import (
18+
"github.com/mitchellh/mapstructure"
1819
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1920

2021
"github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1"
@@ -39,6 +40,10 @@ func TargetAllocator(params manifests.Params) (*v1alpha1.TargetAllocator, error)
3940
if err != nil {
4041
return nil, err
4142
}
43+
globalConfig, err := getGlobalConfig(params.OtelCol.Spec.Config)
44+
if err != nil {
45+
return nil, err
46+
}
4247

4348
return &v1alpha1.TargetAllocator{
4449
ObjectMeta: metav1.ObjectMeta{
@@ -66,12 +71,31 @@ func TargetAllocator(params manifests.Params) (*v1alpha1.TargetAllocator, error)
6671
AllocationStrategy: taSpec.AllocationStrategy,
6772
FilterStrategy: taSpec.FilterStrategy,
6873
ScrapeConfigs: scrapeConfigs,
74+
GlobalConfig: globalConfig,
6975
PrometheusCR: taSpec.PrometheusCR,
7076
Observability: taSpec.Observability,
7177
},
7278
}, nil
7379
}
7480

81+
func getGlobalConfig(otelConfig v1beta1.Config) (v1beta1.AnyConfig, error) {
82+
// TODO: Eventually we should figure out a way to pull this in to the main specification for the TA
83+
type promReceiverConfig struct {
84+
Prometheus struct {
85+
Config struct {
86+
Global map[string]interface{} `mapstructure:"global"`
87+
} `mapstructure:"config"`
88+
} `mapstructure:"prometheus"`
89+
}
90+
decodedConfig := &promReceiverConfig{}
91+
if err := mapstructure.Decode(otelConfig.Receivers.Object, decodedConfig); err != nil {
92+
return v1beta1.AnyConfig{}, err
93+
}
94+
return v1beta1.AnyConfig{
95+
Object: decodedConfig.Prometheus.Config.Global,
96+
}, nil
97+
}
98+
7599
func getScrapeConfigs(otelcolConfig string) ([]v1beta1.AnyConfig, error) {
76100
// Collector supports environment variable substitution, but the TA does not.
77101
// TA Scrape Configs should have a single "$", as it does not support env var substitution

internal/manifests/collector/targetallocator_test.go

+63
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ func TestTargetAllocator(t *testing.T) {
9191
ObjectMeta: objectMetadata,
9292
Spec: v1alpha1.TargetAllocatorSpec{
9393
ScrapeConfigs: []v1beta1.AnyConfig{},
94+
GlobalConfig: v1beta1.AnyConfig{},
9495
},
9596
},
9697
},
@@ -420,3 +421,65 @@ func TestGetScrapeConfigs(t *testing.T) {
420421
})
421422
}
422423
}
424+
425+
func Test_getGlobalConfig(t *testing.T) {
426+
type args struct {
427+
otelConfig v1beta1.Config
428+
}
429+
tests := []struct {
430+
name string
431+
args args
432+
want v1beta1.AnyConfig
433+
wantErr error
434+
}{
435+
{
436+
name: "Valid Global Config",
437+
args: args{
438+
otelConfig: v1beta1.Config{
439+
Receivers: v1beta1.AnyConfig{
440+
Object: map[string]interface{}{
441+
"prometheus": map[string]interface{}{
442+
"config": map[string]interface{}{
443+
"global": map[string]interface{}{
444+
"scrape_interval": "15s",
445+
"scrape_protocols": []string{"PrometheusProto", "OpenMetricsText1.0.0", "OpenMetricsText0.0.1", "PrometheusText0.0.4"},
446+
},
447+
},
448+
},
449+
},
450+
},
451+
},
452+
},
453+
want: v1beta1.AnyConfig{
454+
Object: map[string]interface{}{
455+
"scrape_interval": "15s",
456+
"scrape_protocols": []string{"PrometheusProto", "OpenMetricsText1.0.0", "OpenMetricsText0.0.1", "PrometheusText0.0.4"},
457+
},
458+
},
459+
wantErr: nil,
460+
},
461+
{
462+
name: "Invalid Global Config - Missing Global",
463+
args: args{
464+
otelConfig: v1beta1.Config{
465+
Receivers: v1beta1.AnyConfig{
466+
Object: map[string]interface{}{
467+
"prometheus": map[string]interface{}{
468+
"config": map[string]interface{}{},
469+
},
470+
},
471+
},
472+
},
473+
},
474+
want: v1beta1.AnyConfig{},
475+
wantErr: nil,
476+
},
477+
}
478+
for _, tt := range tests {
479+
t.Run(tt.name, func(t *testing.T) {
480+
got, err := getGlobalConfig(tt.args.otelConfig)
481+
assert.Equal(t, tt.wantErr, err)
482+
assert.Equal(t, tt.want, got)
483+
})
484+
}
485+
}

internal/manifests/targetallocator/configmap.go

+9-3
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,17 @@ func ConfigMap(params Params) (*corev1.ConfigMap, error) {
4141
MatchLabels: manifestutils.SelectorLabels(params.Collector.ObjectMeta, collector.ComponentOpenTelemetryCollector),
4242
}
4343

44+
// Set config if global or scrape configs set
45+
config := map[string]interface{}{}
46+
if instance.Spec.GlobalConfig.Object != nil {
47+
config["global"] = instance.Spec.GlobalConfig
48+
}
4449
// Add scrape configs if present
4550
if instance.Spec.ScrapeConfigs != nil && len(instance.Spec.ScrapeConfigs) > 0 {
46-
taConfig["config"] = map[string]interface{}{
47-
"scrape_configs": instance.Spec.ScrapeConfigs,
48-
}
51+
config["scrape_configs"] = instance.Spec.ScrapeConfigs
52+
}
53+
if len(config) != 0 {
54+
taConfig["config"] = config
4955
}
5056

5157
if len(taSpec.AllocationStrategy) > 0 {

internal/manifests/targetallocator/configmap_test.go

+13-1
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,13 @@ collector_selector:
118118
app.kubernetes.io/part-of: opentelemetry
119119
matchexpressions: []
120120
config:
121+
global:
122+
scrape_interval: 30s
123+
scrape_protocols:
124+
- PrometheusProto
125+
- OpenMetricsText1.0.0
126+
- OpenMetricsText0.0.1
127+
- PrometheusText0.0.4
121128
scrape_configs:
122129
- job_name: otel-collector
123130
scrape_interval: 10s
@@ -149,10 +156,15 @@ prometheus_cr:
149156
MatchLabels: map[string]string{
150157
"release": "my-instance",
151158
}}
159+
targetAllocator.Spec.GlobalConfig = v1beta1.AnyConfig{
160+
Object: map[string]interface{}{
161+
"scrape_interval": "30s",
162+
"scrape_protocols": []string{"PrometheusProto", "OpenMetricsText1.0.0", "OpenMetricsText0.0.1", "PrometheusText0.0.4"},
163+
},
164+
}
152165
params.TargetAllocator = targetAllocator
153166
actual, err := ConfigMap(params)
154167
assert.NoError(t, err)
155-
156168
assert.Equal(t, "my-instance-targetallocator", actual.Name)
157169
assert.Equal(t, expectedLabels, actual.Labels)
158170
assert.Equal(t, expectedData, actual.Data)

tests/e2e/smoke-targetallocator/00-assert.yaml

+9-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,14 @@ data:
3030
protocols:
3131
grpc: null
3232
prometheus:
33-
config: {}
33+
config:
34+
global:
35+
scrape_interval: 30s
36+
scrape_protocols:
37+
- PrometheusProto
38+
- OpenMetricsText1.0.0
39+
- OpenMetricsText0.0.1
40+
- PrometheusText0.0.4
3441
target_allocator:
3542
collector_id: ${POD_NAME}
3643
endpoint: http://stateful-targetallocator.chainsaw-smoke-targetallocator.svc.cluster.local:80
@@ -44,4 +51,4 @@ data:
4451
- jaeger
4552
kind: ConfigMap
4653
metadata:
47-
name: stateful-collector-2687b61c
54+
name: stateful-collector-eebfc9d2

tests/e2e/smoke-targetallocator/00-install.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ spec:
4646
# Collect own metrics
4747
prometheus:
4848
config:
49+
global:
50+
scrape_interval: 30s
51+
scrape_protocols: ['PrometheusProto','OpenMetricsText1.0.0','OpenMetricsText0.0.1','PrometheusText0.0.4']
4952
scrape_configs:
5053
- job_name: 'otel-collector'
5154
scrape_interval: 10s

tests/e2e/smoke-targetallocator/chainsaw-test.yaml

+35
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,41 @@ spec:
1717
catch:
1818
- podLogs:
1919
selector: app.kubernetes.io/component=opentelemetry-targetallocator
20+
- name: assert-data-propagates
21+
try:
22+
- assert:
23+
resource:
24+
apiVersion: v1
25+
kind: ConfigMap
26+
metadata:
27+
name: stateful-targetallocator
28+
namespace: ($namespace)
29+
data:
30+
targetallocator.yaml:
31+
(parse_yaml(@)):
32+
allocation_strategy: consistent-hashing
33+
collector_selector:
34+
matchlabels:
35+
app.kubernetes.io/component: opentelemetry-collector
36+
app.kubernetes.io/instance: (join('.', [$namespace, 'stateful']))
37+
app.kubernetes.io/managed-by: opentelemetry-operator
38+
app.kubernetes.io/part-of: opentelemetry
39+
matchexpressions: [ ]
40+
config:
41+
global:
42+
scrape_interval: 30s
43+
scrape_protocols:
44+
- PrometheusProto
45+
- OpenMetricsText1.0.0
46+
- OpenMetricsText0.0.1
47+
- PrometheusText0.0.4
48+
scrape_configs:
49+
- job_name: otel-collector
50+
scrape_interval: 10s
51+
static_configs:
52+
- targets:
53+
- 0.0.0.0:8888
54+
filter_strategy: relabel-config
2055
- name: step-01
2156
try:
2257
- apply:

0 commit comments

Comments
 (0)