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

Propagate global scrape protocols by allowing for global config setting #3161

Merged
Merged
Show file tree
Hide file tree
Changes from 7 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
16 changes: 16 additions & 0 deletions .chloggen/propagate-global-scrape-protocols.yaml
Original file line number Diff line number Diff line change
@@ -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. collector, target allocator, auto-instrumentation, opamp, 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: introduces the global field in the TA config to allow for setting scrape protocols

# One or more tracking issues related to the change
issues: [3160]

# (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:
3 changes: 3 additions & 0 deletions apis/v1alpha1/targetallocator_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ type TargetAllocatorSpec struct {
// +optional
// +kubebuilder:default:=relabel-config
FilterStrategy v1beta1.TargetAllocatorFilterStrategy `json:"filterStrategy,omitempty"`
// GlobalConfig configures the global configuration for Prometheus
// For the exact format, see https://github.com/prometheus/prometheus/blob/main/config/config.go#L409-L448
jaronoff97 marked this conversation as resolved.
Show resolved Hide resolved
GlobalConfig v1beta1.AnyConfig `json:"global,omitempty"`
// ScrapeConfigs define static Prometheus scrape configurations for the target allocator.
// To use dynamic configurations from ServiceMonitors and PodMonitors, see the PrometheusCR section.
// For the exact format, see https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config.
Expand Down
1 change: 1 addition & 0 deletions apis/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions config/crd/bases/opentelemetry.io_targetallocators.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1248,6 +1248,8 @@ spec:
- ""
- relabel-config
type: string
global:
type: object
hostNetwork:
type: boolean
image:
Expand Down
24 changes: 24 additions & 0 deletions internal/manifests/collector/targetallocator.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package collector

import (
"github.com/mitchellh/mapstructure"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1"
Expand All @@ -39,6 +40,10 @@ func TargetAllocator(params manifests.Params) (*v1alpha1.TargetAllocator, error)
if err != nil {
return nil, err
}
globalConfig, err := getGlobalConfig(params.OtelCol.Spec.Config)
if err != nil {
return nil, err
}

return &v1alpha1.TargetAllocator{
ObjectMeta: metav1.ObjectMeta{
Expand Down Expand Up @@ -66,12 +71,31 @@ func TargetAllocator(params manifests.Params) (*v1alpha1.TargetAllocator, error)
AllocationStrategy: taSpec.AllocationStrategy,
FilterStrategy: taSpec.FilterStrategy,
ScrapeConfigs: scrapeConfigs,
GlobalConfig: globalConfig,
PrometheusCR: taSpec.PrometheusCR,
Observability: taSpec.Observability,
},
}, nil
}

func getGlobalConfig(otelConfig v1beta1.Config) (v1beta1.AnyConfig, error) {
// TODO: Eventually we should figure out a way to pull this in to the main specification for the TA
type promReceiverConfig struct {
Prometheus struct {
Config struct {
Global map[string]interface{} `mapstructure:"global"`
} `mapstructure:"config"`
} `mapstructure:"prometheus"`
}
decodedConfig := &promReceiverConfig{}
if err := mapstructure.Decode(otelConfig.Receivers.Object, decodedConfig); err != nil {
return v1beta1.AnyConfig{}, err
}
return v1beta1.AnyConfig{
Object: decodedConfig.Prometheus.Config.Global,
}, nil
}

func getScrapeConfigs(otelcolConfig string) ([]v1beta1.AnyConfig, error) {
// Collector supports environment variable substitution, but the TA does not.
// TA Scrape Configs should have a single "$", as it does not support env var substitution
Expand Down
63 changes: 63 additions & 0 deletions internal/manifests/collector/targetallocator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ func TestTargetAllocator(t *testing.T) {
ObjectMeta: objectMetadata,
Spec: v1alpha1.TargetAllocatorSpec{
ScrapeConfigs: []v1beta1.AnyConfig{},
GlobalConfig: v1beta1.AnyConfig{},
},
},
},
Expand Down Expand Up @@ -420,3 +421,65 @@ func TestGetScrapeConfigs(t *testing.T) {
})
}
}

func Test_getGlobalConfig(t *testing.T) {
type args struct {
otelConfig v1beta1.Config
}
tests := []struct {
name string
args args
want v1beta1.AnyConfig
wantErr error
}{
{
name: "Valid Global Config",
args: args{
otelConfig: v1beta1.Config{
Receivers: v1beta1.AnyConfig{
Object: map[string]interface{}{
"prometheus": map[string]interface{}{
"config": map[string]interface{}{
"global": map[string]interface{}{
"scrape_interval": "15s",
"scrape_protocols": []string{"PrometheusProto", "OpenMetricsText1.0.0", "OpenMetricsText0.0.1", "PrometheusText0.0.4"},
},
},
},
},
},
},
},
want: v1beta1.AnyConfig{
Object: map[string]interface{}{
"scrape_interval": "15s",
"scrape_protocols": []string{"PrometheusProto", "OpenMetricsText1.0.0", "OpenMetricsText0.0.1", "PrometheusText0.0.4"},
},
},
wantErr: nil,
},
{
name: "Invalid Global Config - Missing Global",
args: args{
otelConfig: v1beta1.Config{
Receivers: v1beta1.AnyConfig{
Object: map[string]interface{}{
"prometheus": map[string]interface{}{
"config": map[string]interface{}{},
},
},
},
},
},
want: v1beta1.AnyConfig{},
wantErr: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := getGlobalConfig(tt.args.otelConfig)
assert.Equal(t, tt.wantErr, err)
assert.Equal(t, tt.want, got)
})
}
}
12 changes: 9 additions & 3 deletions internal/manifests/targetallocator/configmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,17 @@ func ConfigMap(params Params) (*corev1.ConfigMap, error) {
MatchLabels: manifestutils.SelectorLabels(params.Collector.ObjectMeta, collector.ComponentOpenTelemetryCollector),
}

// Set config if global or scrape configs set
config := map[string]interface{}{}
if instance.Spec.GlobalConfig.Object != nil {
config["global"] = instance.Spec.GlobalConfig
}
// Add scrape configs if present
if instance.Spec.ScrapeConfigs != nil && len(instance.Spec.ScrapeConfigs) > 0 {
taConfig["config"] = map[string]interface{}{
"scrape_configs": instance.Spec.ScrapeConfigs,
}
config["scrape_configs"] = instance.Spec.ScrapeConfigs
}
if len(config) != 0 {
taConfig["config"] = config
}

if len(taSpec.AllocationStrategy) > 0 {
Expand Down
14 changes: 13 additions & 1 deletion internal/manifests/targetallocator/configmap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,13 @@ collector_selector:
app.kubernetes.io/part-of: opentelemetry
matchexpressions: []
config:
global:
scrape_interval: 30s
scrape_protocols:
- PrometheusProto
- OpenMetricsText1.0.0
- OpenMetricsText0.0.1
- PrometheusText0.0.4
scrape_configs:
- job_name: otel-collector
scrape_interval: 10s
Expand Down Expand Up @@ -149,10 +156,15 @@ prometheus_cr:
MatchLabels: map[string]string{
"release": "my-instance",
}}
targetAllocator.Spec.GlobalConfig = v1beta1.AnyConfig{
Object: map[string]interface{}{
"scrape_interval": "30s",
"scrape_protocols": []string{"PrometheusProto", "OpenMetricsText1.0.0", "OpenMetricsText0.0.1", "PrometheusText0.0.4"},
},
}
params.TargetAllocator = targetAllocator
actual, err := ConfigMap(params)
assert.NoError(t, err)

assert.Equal(t, "my-instance-targetallocator", actual.Name)
assert.Equal(t, expectedLabels, actual.Labels)
assert.Equal(t, expectedData, actual.Data)
Expand Down
11 changes: 9 additions & 2 deletions tests/e2e/smoke-targetallocator/00-assert.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,14 @@ data:
protocols:
grpc: null
prometheus:
config: {}
config:
global:
scrape_interval: 30s
scrape_protocols:
- PrometheusProto
- OpenMetricsText1.0.0
- OpenMetricsText0.0.1
- PrometheusText0.0.4
target_allocator:
collector_id: ${POD_NAME}
endpoint: http://stateful-targetallocator:80
Expand All @@ -44,4 +51,4 @@ data:
- jaeger
kind: ConfigMap
metadata:
name: stateful-collector-2687b61c
name: stateful-collector-eebfc9d2
3 changes: 3 additions & 0 deletions tests/e2e/smoke-targetallocator/00-install.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ spec:
# Collect own metrics
prometheus:
config:
global:
scrape_interval: 30s
scrape_protocols: ['PrometheusProto','OpenMetricsText1.0.0','OpenMetricsText0.0.1','PrometheusText0.0.4']
scrape_configs:
- job_name: 'otel-collector'
scrape_interval: 10s
Expand Down
35 changes: 35 additions & 0 deletions tests/e2e/smoke-targetallocator/chainsaw-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,41 @@ spec:
catch:
- podLogs:
selector: app.kubernetes.io/component=opentelemetry-targetallocator
- name: assert-data-propagates
try:
- assert:
resource:
apiVersion: v1
kind: ConfigMap
metadata:
name: stateful-targetallocator
namespace: ($namespace)
data:
targetallocator.yaml:
(parse_yaml(@)):
allocation_strategy: consistent-hashing
collector_selector:
matchlabels:
app.kubernetes.io/component: opentelemetry-collector
app.kubernetes.io/instance: (join('.', [$namespace, 'stateful']))
app.kubernetes.io/managed-by: opentelemetry-operator
app.kubernetes.io/part-of: opentelemetry
matchexpressions: [ ]
config:
global:
scrape_interval: 30s
scrape_protocols:
- PrometheusProto
- OpenMetricsText1.0.0
- OpenMetricsText0.0.1
- PrometheusText0.0.4
scrape_configs:
- job_name: otel-collector
scrape_interval: 10s
static_configs:
- targets:
- 0.0.0.0:8888
filter_strategy: relabel-config
- name: step-01
try:
- apply:
Expand Down
Loading