diff --git a/.chloggen/3446.yaml b/.chloggen/3446.yaml new file mode 100755 index 0000000000..a8cb5de7ad --- /dev/null +++ b/.chloggen/3446.yaml @@ -0,0 +1,19 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: 'bug_fix' + +# 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: operator + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Operator pod crashed if the Service Monitor for the operator metrics was created before by another operator pod. + +# One or more tracking issues related to the change +issues: [3446] + +# (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: | + Operator fails when the pod is restarted and the Service Monitor for operator metrics was already created by another operator pod. + To fix this, the operator now sets the owner reference on the Service Monitor to itself and checks if the Service Monitor already exists. + diff --git a/.github/workflows/continuous-integration.yaml b/.github/workflows/continuous-integration.yaml index 829789c19a..dd0fc335f6 100644 --- a/.github/workflows/continuous-integration.yaml +++ b/.github/workflows/continuous-integration.yaml @@ -62,8 +62,6 @@ jobs: with: path: | /home/runner/.cache/golangci-lint - /home/runner/go/pkg/mod - ./bin key: golangcilint-${{ hashFiles('**/go.sum') }} restore-keys: | golangcilint- diff --git a/autoinstrumentation/java/version.txt b/autoinstrumentation/java/version.txt index c8e38b6140..10c2c0c3d6 100644 --- a/autoinstrumentation/java/version.txt +++ b/autoinstrumentation/java/version.txt @@ -1 +1 @@ -2.9.0 +2.10.0 diff --git a/cmd/otel-allocator/allocation/allocator_test.go b/cmd/otel-allocator/allocation/allocator_test.go index 55f2bb6dc6..e6c2b9693a 100644 --- a/cmd/otel-allocator/allocation/allocator_test.go +++ b/cmd/otel-allocator/allocation/allocator_test.go @@ -17,7 +17,7 @@ package allocation import ( "testing" - "github.com/prometheus/common/model" + "github.com/prometheus/prometheus/model/labels" "github.com/stretchr/testify/assert" "github.com/open-telemetry/opentelemetry-operator/cmd/otel-allocator/target" @@ -176,11 +176,11 @@ func TestAllocationCollision(t *testing.T) { cols := MakeNCollectors(3, 0) allocator.SetCollectors(cols) - firstLabels := model.LabelSet{ - "test": "test1", + firstLabels := labels.Labels{ + {Name: "test", Value: "test1"}, } - secondLabels := model.LabelSet{ - "test": "test2", + secondLabels := labels.Labels{ + {Name: "test", Value: "test2"}, } firstTarget := target.NewItem("sample-name", "0.0.0.0:8000", firstLabels, "") secondTarget := target.NewItem("sample-name", "0.0.0.0:8000", secondLabels, "") diff --git a/cmd/otel-allocator/allocation/consistent_hashing.go b/cmd/otel-allocator/allocation/consistent_hashing.go index 8ec07ba857..9659b73a0d 100644 --- a/cmd/otel-allocator/allocation/consistent_hashing.go +++ b/cmd/otel-allocator/allocation/consistent_hashing.go @@ -16,7 +16,6 @@ package allocation import ( "fmt" - "strings" "github.com/buraksezer/consistent" "github.com/cespare/xxhash/v2" @@ -59,7 +58,7 @@ func (s *consistentHashingStrategy) GetName() string { } func (s *consistentHashingStrategy) GetCollectorForTarget(collectors map[string]*Collector, item *target.Item) (*Collector, error) { - hashKey := strings.Join(item.TargetURL, "") + hashKey := item.TargetURL member := s.consistentHasher.LocateKey([]byte(hashKey)) collectorName := member.String() collector, ok := collectors[collectorName] diff --git a/cmd/otel-allocator/allocation/per_node_test.go b/cmd/otel-allocator/allocation/per_node_test.go index d853574a11..ebbe3f31e6 100644 --- a/cmd/otel-allocator/allocation/per_node_test.go +++ b/cmd/otel-allocator/allocation/per_node_test.go @@ -17,7 +17,7 @@ package allocation import ( "testing" - "github.com/prometheus/common/model" + "github.com/prometheus/prometheus/model/labels" "github.com/stretchr/testify/assert" logf "sigs.k8s.io/controller-runtime/pkg/log" @@ -33,23 +33,23 @@ func TestAllocationPerNode(t *testing.T) { cols := MakeNCollectors(4, 0) s.SetCollectors(cols) - firstLabels := model.LabelSet{ - "test": "test1", - "__meta_kubernetes_pod_node_name": "node-0", + firstLabels := labels.Labels{ + {Name: "test", Value: "test1"}, + {Name: "__meta_kubernetes_pod_node_name", Value: "node-0"}, } - secondLabels := model.LabelSet{ - "test": "test2", - "__meta_kubernetes_node_name": "node-1", + secondLabels := labels.Labels{ + {Name: "test", Value: "test2"}, + {Name: "__meta_kubernetes_node_name", Value: "node-1"}, } // no label, should be skipped - thirdLabels := model.LabelSet{ - "test": "test3", + thirdLabels := labels.Labels{ + {Name: "test", Value: "test3"}, } // endpointslice target kind and name - fourthLabels := model.LabelSet{ - "test": "test4", - "__meta_kubernetes_endpointslice_address_target_kind": "Node", - "__meta_kubernetes_endpointslice_address_target_name": "node-3", + fourthLabels := labels.Labels{ + {Name: "test", Value: "test4"}, + {Name: "__meta_kubernetes_endpointslice_address_target_kind", Value: "Node"}, + {Name: "__meta_kubernetes_endpointslice_address_target_name", Value: "node-3"}, } firstTarget := target.NewItem("sample-name", "0.0.0.0:8000", firstLabels, "") diff --git a/cmd/otel-allocator/allocation/testutils.go b/cmd/otel-allocator/allocation/testutils.go index 054e9e0205..3189b576c1 100644 --- a/cmd/otel-allocator/allocation/testutils.go +++ b/cmd/otel-allocator/allocation/testutils.go @@ -21,7 +21,7 @@ import ( "strconv" "testing" - "github.com/prometheus/common/model" + "github.com/prometheus/prometheus/model/labels" "github.com/stretchr/testify/require" logf "sigs.k8s.io/controller-runtime/pkg/log" @@ -39,9 +39,9 @@ func MakeNNewTargets(n int, numCollectors int, startingIndex int) map[string]*ta toReturn := map[string]*target.Item{} for i := startingIndex; i < n+startingIndex; i++ { collector := fmt.Sprintf("collector-%d", colIndex(i, numCollectors)) - label := model.LabelSet{ - "i": model.LabelValue(strconv.Itoa(i)), - "total": model.LabelValue(strconv.Itoa(n + startingIndex)), + label := labels.Labels{ + {Name: "i", Value: strconv.Itoa(i)}, + {Name: "total", Value: strconv.Itoa(n + startingIndex)}, } newTarget := target.NewItem(fmt.Sprintf("test-job-%d", i), fmt.Sprintf("test-url-%d", i), label, collector) toReturn[newTarget.Hash()] = newTarget @@ -65,10 +65,10 @@ func MakeNCollectors(n int, startingIndex int) map[string]*Collector { func MakeNNewTargetsWithEmptyCollectors(n int, startingIndex int) map[string]*target.Item { toReturn := map[string]*target.Item{} for i := startingIndex; i < n+startingIndex; i++ { - label := model.LabelSet{ - "i": model.LabelValue(strconv.Itoa(i)), - "total": model.LabelValue(strconv.Itoa(n + startingIndex)), - "__meta_kubernetes_pod_node_name": model.LabelValue("node-0"), + label := labels.Labels{ + {Name: "i", Value: strconv.Itoa(i)}, + {Name: "total", Value: strconv.Itoa(n + startingIndex)}, + {Name: "__meta_kubernetes_pod_node_name", Value: "node-0"}, } newTarget := target.NewItem(fmt.Sprintf("test-job-%d", i), fmt.Sprintf("test-url-%d", i), label, "") toReturn[newTarget.Hash()] = newTarget diff --git a/cmd/otel-allocator/benchmark_test.go b/cmd/otel-allocator/benchmark_test.go index 736b92c208..7b6c644347 100644 --- a/cmd/otel-allocator/benchmark_test.go +++ b/cmd/otel-allocator/benchmark_test.go @@ -18,6 +18,8 @@ import ( "context" "fmt" "os" + "strconv" + "strings" "testing" gokitlog "github.com/go-kit/log" @@ -26,7 +28,9 @@ import ( "github.com/prometheus/common/model" "github.com/prometheus/prometheus/discovery" "github.com/prometheus/prometheus/discovery/targetgroup" + "github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/model/relabel" + "github.com/stretchr/testify/require" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/log" @@ -45,13 +49,14 @@ func BenchmarkProcessTargets(b *testing.B) { targetsPerGroup := 5 groupsPerJob := 20 tsets := prepareBenchmarkData(numTargets, targetsPerGroup, groupsPerJob) + labelsBuilder := labels.NewBuilder(labels.EmptyLabels()) b.ResetTimer() for _, strategy := range allocation.GetRegisteredAllocatorNames() { b.Run(strategy, func(b *testing.B) { targetDiscoverer, allocator := createTestDiscoverer(strategy, map[string][]*relabel.Config{}) for i := 0; i < b.N; i++ { - targetDiscoverer.ProcessTargets(tsets, allocator.SetTargets) + targetDiscoverer.ProcessTargets(labelsBuilder, tsets, allocator.SetTargets) } }) } @@ -64,12 +69,24 @@ func BenchmarkProcessTargetsWithRelabelConfig(b *testing.B) { targetsPerGroup := 5 groupsPerJob := 20 tsets := prepareBenchmarkData(numTargets, targetsPerGroup, groupsPerJob) + labelsBuilder := labels.NewBuilder(labels.EmptyLabels()) prehookConfig := make(map[string][]*relabel.Config, len(tsets)) for jobName := range tsets { + // keep all targets in half the jobs, drop the rest + jobNrStr := strings.Split(jobName, "-")[1] + jobNr, err := strconv.Atoi(jobNrStr) + require.NoError(b, err) + var action relabel.Action + if jobNr%2 == 0 { + action = "keep" + } else { + action = "drop" + } prehookConfig[jobName] = []*relabel.Config{ { - Action: "keep", - Regex: relabel.MustNewRegexp(".*"), + Action: action, + Regex: relabel.MustNewRegexp(".*"), + SourceLabels: model.LabelNames{"__address__"}, }, } } @@ -79,7 +96,7 @@ func BenchmarkProcessTargetsWithRelabelConfig(b *testing.B) { b.Run(strategy, func(b *testing.B) { targetDiscoverer, allocator := createTestDiscoverer(strategy, prehookConfig) for i := 0; i < b.N; i++ { - targetDiscoverer.ProcessTargets(tsets, allocator.SetTargets) + targetDiscoverer.ProcessTargets(labelsBuilder, tsets, allocator.SetTargets) } }) } diff --git a/cmd/otel-allocator/prehook/relabel.go b/cmd/otel-allocator/prehook/relabel.go index 3595cb888e..6c96affa39 100644 --- a/cmd/otel-allocator/prehook/relabel.go +++ b/cmd/otel-allocator/prehook/relabel.go @@ -16,8 +16,6 @@ package prehook import ( "github.com/go-logr/logr" - "github.com/prometheus/common/model" - "github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/model/relabel" "github.com/open-telemetry/opentelemetry-operator/cmd/otel-allocator/target" @@ -35,18 +33,6 @@ func NewRelabelConfigTargetFilter(log logr.Logger) Hook { } } -// helper function converts from model.LabelSet to []labels.Label. -func convertLabelToPromLabelSet(lbls model.LabelSet) []labels.Label { - newLabels := make([]labels.Label, len(lbls)) - index := 0 - for k, v := range lbls { - newLabels[index].Name = string(k) - newLabels[index].Value = string(v) - index++ - } - return newLabels -} - func (tf *RelabelConfigTargetFilter) Apply(targets map[string]*target.Item) map[string]*target.Item { numTargets := len(targets) @@ -57,20 +43,15 @@ func (tf *RelabelConfigTargetFilter) Apply(targets map[string]*target.Item) map[ // Note: jobNameKey != tItem.JobName (jobNameKey is hashed) for jobNameKey, tItem := range targets { - keepTarget := true - lset := convertLabelToPromLabelSet(tItem.Labels) + var keepTarget bool + lset := tItem.Labels for _, cfg := range tf.relabelCfg[tItem.JobName] { - if newLset, keep := relabel.Process(lset, cfg); !keep { - keepTarget = false + lset, keepTarget = relabel.Process(lset, cfg) + if !keepTarget { + delete(targets, jobNameKey) break // inner loop - } else { - lset = newLset } } - - if !keepTarget { - delete(targets, jobNameKey) - } } tf.log.V(2).Info("Filtering complete", "seen", numTargets, "kept", len(targets)) diff --git a/cmd/otel-allocator/prehook/relabel_test.go b/cmd/otel-allocator/prehook/relabel_test.go index d30f645eba..9aa27764ca 100644 --- a/cmd/otel-allocator/prehook/relabel_test.go +++ b/cmd/otel-allocator/prehook/relabel_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/prometheus/common/model" + "github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/model/relabel" "github.com/stretchr/testify/assert" logf "sigs.k8s.io/controller-runtime/pkg/log" @@ -184,10 +185,10 @@ func makeNNewTargets(rCfgs []relabelConfigObj, n int, numCollectors int, startin relabelConfig := make(map[string][]*relabel.Config) for i := startingIndex; i < n+startingIndex; i++ { collector := fmt.Sprintf("collector-%d", colIndex(i, numCollectors)) - label := model.LabelSet{ - "collector": model.LabelValue(collector), - "i": model.LabelValue(strconv.Itoa(i)), - "total": model.LabelValue(strconv.Itoa(n + startingIndex)), + label := labels.Labels{ + {Name: "collector", Value: collector}, + {Name: "i", Value: strconv.Itoa(i)}, + {Name: "total", Value: strconv.Itoa(n + startingIndex)}, } jobName := fmt.Sprintf("test-job-%d", i) newTarget := target.NewItem(jobName, "test-url", label, collector) diff --git a/cmd/otel-allocator/server/bench_test.go b/cmd/otel-allocator/server/bench_test.go index b4f24f480d..d441fd8e2c 100644 --- a/cmd/otel-allocator/server/bench_test.go +++ b/cmd/otel-allocator/server/bench_test.go @@ -24,6 +24,7 @@ import ( "github.com/gin-gonic/gin" "github.com/prometheus/common/model" promconfig "github.com/prometheus/prometheus/config" + "github.com/prometheus/prometheus/model/labels" "github.com/stretchr/testify/assert" "github.com/open-telemetry/opentelemetry-operator/cmd/otel-allocator/allocation" @@ -249,12 +250,13 @@ func makeNCollectorJSON(random rand.Rand, numCollectors, numItems int) map[strin } func makeNTargetItems(random rand.Rand, numItems, numLabels int) []*target.Item { + builder := labels.NewBuilder(labels.EmptyLabels()) items := make([]*target.Item, 0, numItems) for i := 0; i < numItems; i++ { items = append(items, target.NewItem( randSeq(random, 80), randSeq(random, 150), - makeNNewLabels(random, numLabels), + makeNNewLabels(builder, random, numLabels), randSeq(random, 30), )) } @@ -270,10 +272,10 @@ func makeNTargetJSON(random rand.Rand, numItems, numLabels int) []*targetJSON { return targets } -func makeNNewLabels(random rand.Rand, n int) model.LabelSet { - labels := make(map[model.LabelName]model.LabelValue, n) +func makeNNewLabels(builder *labels.Builder, random rand.Rand, n int) labels.Labels { + builder.Reset(labels.EmptyLabels()) for i := 0; i < n; i++ { - labels[model.LabelName(randSeq(random, 20))] = model.LabelValue(randSeq(random, 20)) + builder.Set(randSeq(random, 20), randSeq(random, 20)) } - return labels + return builder.Labels() } diff --git a/cmd/otel-allocator/server/server.go b/cmd/otel-allocator/server/server.go index cb5e1d1873..2e9df9a8b0 100644 --- a/cmd/otel-allocator/server/server.go +++ b/cmd/otel-allocator/server/server.go @@ -34,8 +34,8 @@ import ( "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promhttp" promcommconfig "github.com/prometheus/common/config" - "github.com/prometheus/common/model" promconfig "github.com/prometheus/prometheus/config" + "github.com/prometheus/prometheus/model/labels" "gopkg.in/yaml.v2" "github.com/open-telemetry/opentelemetry-operator/cmd/otel-allocator/allocation" @@ -67,8 +67,8 @@ type linkJSON struct { } type targetJSON struct { - TargetURL []string `json:"targets"` - Labels model.LabelSet `json:"labels"` + TargetURL []string `json:"targets"` + Labels labels.Labels `json:"labels"` } type Server struct { @@ -374,7 +374,7 @@ func registerPprof(g *gin.RouterGroup) { func targetJsonFromTargetItem(item *target.Item) *targetJSON { return &targetJSON{ - TargetURL: item.TargetURL, + TargetURL: []string{item.TargetURL}, Labels: item.Labels, } } diff --git a/cmd/otel-allocator/server/server_test.go b/cmd/otel-allocator/server/server_test.go index b7f9ad73b5..4bc403251c 100644 --- a/cmd/otel-allocator/server/server_test.go +++ b/cmd/otel-allocator/server/server_test.go @@ -28,6 +28,7 @@ import ( "github.com/prometheus/common/config" "github.com/prometheus/common/model" promconfig "github.com/prometheus/prometheus/config" + "github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/model/relabel" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -41,11 +42,11 @@ import ( var ( logger = logf.Log.WithName("server-unit-tests") - baseLabelSet = model.LabelSet{ - "test_label": "test-value", + baseLabelSet = labels.Labels{ + {Name: "test_label", Value: "test-value"}, } - testJobLabelSetTwo = model.LabelSet{ - "test_label": "test-value2", + testJobLabelSetTwo = labels.Labels{ + {Name: "test_label", Value: "test-value2"}, } baseTargetItem = target.NewItem("test-job", "test-url", baseLabelSet, "test-collector") secondTargetItem = target.NewItem("test-job", "test-url", baseLabelSet, "test-collector") @@ -108,8 +109,8 @@ func TestServer_TargetsHandler(t *testing.T) { items: []*targetJSON{ { TargetURL: []string{"test-url"}, - Labels: map[model.LabelName]model.LabelValue{ - "test_label": "test-value", + Labels: labels.Labels{ + {Name: "test_label", Value: "test-value"}, }, }, }, @@ -130,8 +131,8 @@ func TestServer_TargetsHandler(t *testing.T) { items: []*targetJSON{ { TargetURL: []string{"test-url"}, - Labels: map[model.LabelName]model.LabelValue{ - "test_label": "test-value", + Labels: labels.Labels{ + {Name: "test_label", Value: "test-value"}, }, }, }, @@ -152,14 +153,14 @@ func TestServer_TargetsHandler(t *testing.T) { items: []*targetJSON{ { TargetURL: []string{"test-url"}, - Labels: map[model.LabelName]model.LabelValue{ - "test_label": "test-value", + Labels: labels.Labels{ + {Name: "test_label", Value: "test-value"}, }, }, { TargetURL: []string{"test-url2"}, - Labels: map[model.LabelName]model.LabelValue{ - "test_label": "test-value2", + Labels: labels.Labels{ + {Name: "test_label", Value: "test-value2"}, }, }, }, @@ -572,7 +573,7 @@ func TestServer_JobHandler(t *testing.T) { { description: "one job", targetItems: map[string]*target.Item{ - "targetitem": target.NewItem("job1", "", model.LabelSet{}, ""), + "targetitem": target.NewItem("job1", "", labels.Labels{}, ""), }, expectedCode: http.StatusOK, expectedJobs: map[string]linkJSON{ @@ -582,11 +583,11 @@ func TestServer_JobHandler(t *testing.T) { { description: "multiple jobs", targetItems: map[string]*target.Item{ - "a": target.NewItem("job1", "", model.LabelSet{}, ""), - "b": target.NewItem("job2", "", model.LabelSet{}, ""), - "c": target.NewItem("job3", "", model.LabelSet{}, ""), - "d": target.NewItem("job3", "", model.LabelSet{}, ""), - "e": target.NewItem("job3", "", model.LabelSet{}, "")}, + "a": target.NewItem("job1", "", labels.Labels{}, ""), + "b": target.NewItem("job2", "", labels.Labels{}, ""), + "c": target.NewItem("job3", "", labels.Labels{}, ""), + "d": target.NewItem("job3", "", labels.Labels{}, ""), + "e": target.NewItem("job3", "", labels.Labels{}, "")}, expectedCode: http.StatusOK, expectedJobs: map[string]linkJSON{ "job1": newLink("job1"), diff --git a/cmd/otel-allocator/target/discovery.go b/cmd/otel-allocator/target/discovery.go index 6bf68b568a..eb7498e5ad 100644 --- a/cmd/otel-allocator/target/discovery.go +++ b/cmd/otel-allocator/target/discovery.go @@ -25,6 +25,7 @@ import ( promconfig "github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/discovery" "github.com/prometheus/prometheus/discovery/targetgroup" + "github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/model/relabel" "gopkg.in/yaml.v3" @@ -105,26 +106,36 @@ func (m *Discoverer) ApplyConfig(source allocatorWatcher.EventSource, scrapeConf } func (m *Discoverer) Watch(fn func(targets map[string]*Item)) error { + labelsBuilder := labels.NewBuilder(labels.EmptyLabels()) for { select { case <-m.close: m.log.Info("Service Discovery watch event stopped: discovery manager closed") return nil case tsets := <-m.manager.SyncCh(): - m.ProcessTargets(tsets, fn) + m.ProcessTargets(labelsBuilder, tsets, fn) } } } -func (m *Discoverer) ProcessTargets(tsets map[string][]*targetgroup.Group, fn func(targets map[string]*Item)) { +func (m *Discoverer) ProcessTargets(builder *labels.Builder, tsets map[string][]*targetgroup.Group, fn func(targets map[string]*Item)) { targets := map[string]*Item{} for jobName, tgs := range tsets { var count float64 = 0 for _, tg := range tgs { + builder.Reset(labels.EmptyLabels()) + for ln, lv := range tg.Labels { + builder.Set(string(ln), string(lv)) + } + groupLabels := builder.Labels() for _, t := range tg.Targets { count++ - item := NewItem(jobName, string(t[model.AddressLabel]), t.Merge(tg.Labels), "") + builder.Reset(groupLabels) + for ln, lv := range t { + builder.Set(string(ln), string(lv)) + } + item := NewItem(jobName, string(t[model.AddressLabel]), builder.Labels(), "") targets[item.Hash()] = item } } diff --git a/cmd/otel-allocator/target/discovery_test.go b/cmd/otel-allocator/target/discovery_test.go index f773b295c0..7eb2883ee9 100644 --- a/cmd/otel-allocator/target/discovery_test.go +++ b/cmd/otel-allocator/target/discovery_test.go @@ -87,7 +87,7 @@ func TestDiscovery(t *testing.T) { err := manager.Watch(func(targets map[string]*Item) { var result []string for _, t := range targets { - result = append(result, t.TargetURL[0]) + result = append(result, t.TargetURL) } results <- result }) diff --git a/cmd/otel-allocator/target/target.go b/cmd/otel-allocator/target/target.go index ce80450088..5a157bc11d 100644 --- a/cmd/otel-allocator/target/target.go +++ b/cmd/otel-allocator/target/target.go @@ -15,26 +15,29 @@ package target import ( - "github.com/prometheus/common/model" + "strconv" + + "github.com/prometheus/prometheus/model/labels" ) // nodeLabels are labels that are used to identify the node on which the given // target is residing. To learn more about these labels, please refer to: // https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kubernetes_sd_config var ( - nodeLabels = []model.LabelName{ + nodeLabels = []string{ "__meta_kubernetes_pod_node_name", "__meta_kubernetes_node_name", "__meta_kubernetes_endpoint_node_name", } - endpointSliceTargetKindLabel model.LabelName = "__meta_kubernetes_endpointslice_address_target_kind" - endpointSliceTargetNameLabel model.LabelName = "__meta_kubernetes_endpointslice_address_target_name" + endpointSliceTargetKindLabel = "__meta_kubernetes_endpointslice_address_target_kind" + endpointSliceTargetNameLabel = "__meta_kubernetes_endpointslice_address_target_name" + relevantLabelNames = append(nodeLabels, endpointSliceTargetKindLabel, endpointSliceTargetNameLabel) ) type Item struct { JobName string - TargetURL []string - Labels model.LabelSet + TargetURL string + Labels labels.Labels CollectorName string hash string } @@ -44,29 +47,30 @@ func (t *Item) Hash() string { } func (t *Item) GetNodeName() string { + relevantLabels := t.Labels.MatchLabels(true, relevantLabelNames...) for _, label := range nodeLabels { - if val, ok := t.Labels[label]; ok { - return string(val) + if val := relevantLabels.Get(label); val != "" { + return val } } - if val := t.Labels[endpointSliceTargetKindLabel]; val != "Node" { + if val := relevantLabels.Get(endpointSliceTargetKindLabel); val != "Node" { return "" } - return string(t.Labels[endpointSliceTargetNameLabel]) + return relevantLabels.Get(endpointSliceTargetNameLabel) } // NewItem Creates a new target item. // INVARIANTS: // * Item fields must not be modified after creation. // * Item should only be made via its constructor, never directly. -func NewItem(jobName string, targetURL string, label model.LabelSet, collectorName string) *Item { +func NewItem(jobName string, targetURL string, labels labels.Labels, collectorName string) *Item { return &Item{ JobName: jobName, - hash: jobName + targetURL + label.Fingerprint().String(), - TargetURL: []string{targetURL}, - Labels: label, + hash: jobName + targetURL + strconv.FormatUint(labels.Hash(), 10), + TargetURL: targetURL, + Labels: labels, CollectorName: collectorName, } } diff --git a/go.mod b/go.mod index 11d5779daf..144ef45a4d 100644 --- a/go.mod +++ b/go.mod @@ -27,17 +27,17 @@ require ( github.com/prometheus-operator/prometheus-operator/pkg/client v0.76.2 github.com/prometheus/client_golang v1.20.5 github.com/prometheus/common v0.60.1 - github.com/prometheus/prometheus v0.55.0 + github.com/prometheus/prometheus v0.55.1 github.com/shirou/gopsutil v3.21.11+incompatible github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 - go.opentelemetry.io/collector/featuregate v1.18.0 - go.opentelemetry.io/otel v1.31.0 - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.31.0 - go.opentelemetry.io/otel/exporters/prometheus v0.53.0 - go.opentelemetry.io/otel/metric v1.31.0 - go.opentelemetry.io/otel/sdk v1.31.0 - go.opentelemetry.io/otel/sdk/metric v1.31.0 + go.opentelemetry.io/collector/featuregate v1.19.0 + go.opentelemetry.io/otel v1.32.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.32.0 + go.opentelemetry.io/otel/exporters/prometheus v0.54.0 + go.opentelemetry.io/otel/metric v1.32.0 + go.opentelemetry.io/otel/sdk v1.32.0 + go.opentelemetry.io/otel/sdk/metric v1.32.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 gopkg.in/yaml.v2 v2.4.0 @@ -133,7 +133,7 @@ require ( github.com/gophercloud/gophercloud v1.14.0 // indirect github.com/gorilla/websocket v1.5.1 // indirect github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 // indirect github.com/hashicorp/consul/api v1.29.4 // indirect github.com/hashicorp/cronexpr v1.1.2 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect @@ -200,7 +200,7 @@ require ( go.mongodb.org/mongo-driver v1.14.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect - go.opentelemetry.io/otel/trace v1.31.0 // indirect + go.opentelemetry.io/otel/trace v1.32.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/atomic v1.11.0 // indirect golang.org/x/arch v0.8.0 // indirect @@ -209,16 +209,16 @@ require ( golang.org/x/mod v0.21.0 // indirect golang.org/x/net v0.30.0 // indirect golang.org/x/oauth2 v0.23.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.26.0 // indirect + golang.org/x/sync v0.9.0 // indirect + golang.org/x/sys v0.27.0 // indirect golang.org/x/term v0.25.0 // indirect - golang.org/x/text v0.19.0 // indirect + golang.org/x/text v0.20.0 // indirect golang.org/x/time v0.6.0 // indirect golang.org/x/tools v0.25.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/api v0.198.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 // indirect google.golang.org/grpc v1.67.1 // indirect google.golang.org/protobuf v1.35.1 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect diff --git a/go.sum b/go.sum index 6ffb79156b..a62a629ef3 100644 --- a/go.sum +++ b/go.sum @@ -330,8 +330,8 @@ github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/ github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc h1:GN2Lv3MGO7AS6PrRoT6yV5+wkrOpcszoIsO4+4ds248= github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0 h1:ad0vkEBuk23VJzZR9nkLVG0YAoN9coASF1GusYX6AlU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.23.0/go.mod h1:igFoXX2ELCW06bol23DWPB5BEWfZISOzSP5K2sbLea0= github.com/hashicorp/consul/api v1.29.4 h1:P6slzxDLBOxUSj3fWo2o65VuKtbtOXFi7TSSgtXutuE= github.com/hashicorp/consul/api v1.29.4/go.mod h1:HUlfw+l2Zy68ceJavv2zAyArl2fqhGWnMycyt56sBgg= github.com/hashicorp/consul/proto-public v0.6.2 h1:+DA/3g/IiKlJZb88NBn0ZgXrxJp2NlvCZdEyl+qxvL0= @@ -575,8 +575,8 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= -github.com/prometheus/prometheus v0.55.0 h1:ITinOi1zr3HemoVWHf679PfRRmpxZOcR4nEvsze6eB0= -github.com/prometheus/prometheus v0.55.0/go.mod h1:GGS7QlWKCqCbcEzWsVahYIfQwiGhcExkarHyLJTsv6I= +github.com/prometheus/prometheus v0.55.1 h1:+NM9V/h4A+wRkOyQzGewzgPPgq/iX2LUQoISNvmjZmI= +github.com/prometheus/prometheus v0.55.1/go.mod h1:GGS7QlWKCqCbcEzWsVahYIfQwiGhcExkarHyLJTsv6I= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= @@ -646,28 +646,28 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/collector/featuregate v1.18.0 h1:1CvP1K3XmVs7WZCs/A1j8rsC7JQWu+y+vF8vxKjLaOU= -go.opentelemetry.io/collector/featuregate v1.18.0/go.mod h1:47xrISO71vJ83LSMm8+yIDsUbKktUp48Ovt7RR6VbRs= +go.opentelemetry.io/collector/featuregate v1.19.0 h1:ASea2sU+tdpKI3RxIJC/pufDAfwAmrvcQ4EmTHVu0B0= +go.opentelemetry.io/collector/featuregate v1.19.0/go.mod h1:47xrISO71vJ83LSMm8+yIDsUbKktUp48Ovt7RR6VbRs= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8= -go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= -go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.31.0 h1:ZsXq73BERAiNuuFXYqP4MR5hBrjXfMGSO+Cx7qoOZiM= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.31.0/go.mod h1:hg1zaDMpyZJuUzjFxFsRYBoccE86tM9Uf4IqNMUxvrY= +go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U= +go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.32.0 h1:t/Qur3vKSkUCcDVaSumWF2PKHt85pc7fRvFuoVT8qFU= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.32.0/go.mod h1:Rl61tySSdcOJWoEgYZVtmnKdA0GeKrSqkHC1t+91CH8= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 h1:dIIDULZJpgdiHz5tXrTgKIMLkus6jEFa7x5SOKcyR7E= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0/go.mod h1:jlRVBe7+Z1wyxFSUs48L6OBQZ5JwH2Hg/Vbl+t9rAgI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.29.0 h1:JAv0Jwtl01UFiyWZEMiJZBiTlv5A50zNs8lsthXqIio= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.29.0/go.mod h1:QNKLmUEAq2QUbPQUfvw4fmv0bgbK7UlOSFCnXyfvSNc= -go.opentelemetry.io/otel/exporters/prometheus v0.53.0 h1:QXobPHrwiGLM4ufrY3EOmDPJpo2P90UuFau4CDPJA/I= -go.opentelemetry.io/otel/exporters/prometheus v0.53.0/go.mod h1:WOAXGr3D00CfzmFxtTV1eR0GpoHuPEu+HJT8UWW2SIU= -go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= -go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= -go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= -go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= -go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc= -go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8= -go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= -go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= +go.opentelemetry.io/otel/exporters/prometheus v0.54.0 h1:rFwzp68QMgtzu9PgP3jm9XaMICI6TsofWWPcBDKwlsU= +go.opentelemetry.io/otel/exporters/prometheus v0.54.0/go.mod h1:QyjcV9qDP6VeK5qPyKETvNjmaaEc7+gqjh4SS0ZYzDU= +go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M= +go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8= +go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4= +go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU= +go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU= +go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ= +go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM= +go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8= go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= @@ -793,8 +793,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -855,8 +855,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -876,8 +876,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -990,10 +990,10 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 h1:T6rh4haD3GVYsgEfWExoCZA2o2FmbNyKpTuAxbEFPTg= -google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:wp2WsuBYj6j8wUdo3ToZsdxxixbvQNAHqVJrTgi5E5M= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= +google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 h1:M0KvPgPmDZHPlbRbaNU1APr28TvwvvdUPlSv7PUvy8g= +google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:dguCy7UOdZhTvLzDyt15+rOrawrpM4q7DD9dQ1P11P4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 h1:XVhgTWWV3kGQlwJHR3upFWZeTsei6Oks1apkZSeonIE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= diff --git a/internal/operator-metrics/metrics.go b/internal/operator-metrics/metrics.go index 43b3a607e3..dd95e16e7e 100644 --- a/internal/operator-metrics/metrics.go +++ b/internal/operator-metrics/metrics.go @@ -19,8 +19,11 @@ import ( "fmt" "os" + "github.com/go-logr/logr" monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" @@ -51,9 +54,10 @@ var _ manager.Runnable = &OperatorMetrics{} type OperatorMetrics struct { kubeClient client.Client + log logr.Logger } -func NewOperatorMetrics(config *rest.Config, scheme *runtime.Scheme) (OperatorMetrics, error) { +func NewOperatorMetrics(config *rest.Config, scheme *runtime.Scheme, log logr.Logger) (OperatorMetrics, error) { kubeClient, err := client.New(config, client.Options{Scheme: scheme}) if err != nil { return OperatorMetrics{}, err @@ -61,16 +65,74 @@ func NewOperatorMetrics(config *rest.Config, scheme *runtime.Scheme) (OperatorMe return OperatorMetrics{ kubeClient: kubeClient, + log: log, }, nil } func (om OperatorMetrics) Start(ctx context.Context) error { + err := om.createOperatorMetricsServiceMonitor(ctx) + if err != nil { + om.log.Error(err, "error creating Service Monitor for operator metrics") + } + + return nil +} + +func (om OperatorMetrics) NeedLeaderElection() bool { + return true +} + +func (om OperatorMetrics) caConfigMapExists() bool { + return om.kubeClient.Get(context.Background(), client.ObjectKey{ + Name: caBundleConfigMap, + Namespace: openshiftInClusterMonitoringNamespace, + }, &corev1.ConfigMap{}, + ) == nil +} + +func (om OperatorMetrics) getOwnerReferences(ctx context.Context, namespace string) (metav1.OwnerReference, error) { + var deploymentList appsv1.DeploymentList + + listOptions := []client.ListOption{ + client.InNamespace(namespace), + client.MatchingLabels(map[string]string{ + "app.kubernetes.io/name": "opentelemetry-operator", + "control-plane": "controller-manager", + }), + } + + err := om.kubeClient.List(ctx, &deploymentList, listOptions...) + if err != nil { + return metav1.OwnerReference{}, err + } + + if len(deploymentList.Items) == 0 { + return metav1.OwnerReference{}, fmt.Errorf("no deployments found with the specified label") + } + deployment := &deploymentList.Items[0] + + ownerRef := metav1.OwnerReference{ + APIVersion: "apps/v1", + Kind: "Deployment", + Name: deployment.Name, + UID: deployment.UID, + } + + return ownerRef, nil +} + +func (om OperatorMetrics) createOperatorMetricsServiceMonitor(ctx context.Context) error { rawNamespace, err := os.ReadFile(namespaceFile) if err != nil { return fmt.Errorf("error reading namespace file: %w", err) } namespace := string(rawNamespace) + ownerRef, err := om.getOwnerReferences(ctx, namespace) + if err != nil { + return fmt.Errorf("error getting owner references: %w", err) + } + var tlsConfig *monitoringv1.TLSConfig if om.caConfigMapExists() { @@ -101,6 +163,7 @@ func (om OperatorMetrics) Start(ctx context.Context) error { "app.kubernetes.io/part-of": "opentelemetry-operator", "control-plane": "controller-manager", }, + OwnerReferences: []metav1.OwnerReference{ownerRef}, }, Spec: monitoringv1.ServiceMonitorSpec{ Selector: metav1.LabelSelector{ @@ -123,23 +186,12 @@ func (om OperatorMetrics) Start(ctx context.Context) error { } err = om.kubeClient.Create(ctx, &sm) - if err != nil { - return fmt.Errorf("error creating service monitor: %w", err) + // The ServiceMonitor can be already there if this is a restart + if err != nil && !apierrors.IsAlreadyExists(err) { + return err } <-ctx.Done() return om.kubeClient.Delete(ctx, &sm) } - -func (om OperatorMetrics) NeedLeaderElection() bool { - return true -} - -func (om OperatorMetrics) caConfigMapExists() bool { - return om.kubeClient.Get(context.Background(), client.ObjectKey{ - Name: caBundleConfigMap, - Namespace: openshiftInClusterMonitoringNamespace, - }, &corev1.ConfigMap{}, - ) == nil -} diff --git a/internal/operator-metrics/metrics_test.go b/internal/operator-metrics/metrics_test.go index ae625bfff4..a0293fa2e5 100644 --- a/internal/operator-metrics/metrics_test.go +++ b/internal/operator-metrics/metrics_test.go @@ -17,12 +17,15 @@ package operatormetrics import ( "context" "os" + "reflect" "testing" "time" + "github.com/go-logr/logr" monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -30,13 +33,14 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/rest" + "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" ) func TestNewOperatorMetrics(t *testing.T) { config := &rest.Config{} scheme := runtime.NewScheme() - metrics, err := NewOperatorMetrics(config, scheme) + metrics, err := NewOperatorMetrics(config, scheme, logr.Discard()) assert.NoError(t, err) assert.NotNil(t, metrics.kubeClient) } @@ -53,12 +57,15 @@ func TestOperatorMetrics_Start(t *testing.T) { namespaceFile = tmpFile.Name() scheme := runtime.NewScheme() - err = corev1.AddToScheme(scheme) - require.NoError(t, err) - err = monitoringv1.AddToScheme(scheme) - require.NoError(t, err) + require.NoError(t, corev1.AddToScheme(scheme)) + require.NoError(t, appsv1.AddToScheme(scheme)) + require.NoError(t, monitoringv1.AddToScheme(scheme)) - client := fake.NewClientBuilder().WithScheme(scheme).Build() + client := fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects( + &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: "opentelemetry-operator", Namespace: "test-namespace", Labels: map[string]string{"app.kubernetes.io/name": "opentelemetry-operator", "control-plane": "controller-manager"}}, + }, + ).Build() metrics := OperatorMetrics{kubeClient: client} @@ -125,3 +132,70 @@ func TestOperatorMetrics_caConfigMapExists(t *testing.T) { metricsWithoutConfigMap := OperatorMetrics{kubeClient: clientWithoutConfigMap} assert.False(t, metricsWithoutConfigMap.caConfigMapExists()) } + +func TestOperatorMetrics_getOwnerReferences(t *testing.T) { + tests := []struct { + name string + namespace string + objects []client.Object + want metav1.OwnerReference + wantErr bool + }{ + { + name: "successful owner reference retrieval", + namespace: "test-namespace", + objects: []client.Object{ + &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "opentelemetry-operator", + Namespace: "test-namespace", + UID: "test-uid", + Labels: map[string]string{ + "app.kubernetes.io/name": "opentelemetry-operator", + "control-plane": "controller-manager", + }, + }, + }, + }, + want: metav1.OwnerReference{ + APIVersion: "apps/v1", + Kind: "Deployment", + Name: "opentelemetry-operator", + UID: "test-uid", + }, + wantErr: false, + }, + { + name: "no deployments found", + namespace: "test-namespace", + objects: []client.Object{}, + want: metav1.OwnerReference{}, + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + scheme := runtime.NewScheme() + _ = appsv1.AddToScheme(scheme) + fakeClient := fake.NewClientBuilder(). + WithScheme(scheme). + WithObjects(tt.objects...). + Build() + + om := OperatorMetrics{ + kubeClient: fakeClient, + log: logr.Discard(), + } + + got, err := om.getOwnerReferences(context.Background(), tt.namespace) + if (err != nil) != tt.wantErr { + t.Errorf("getOwnerReferences() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("getOwnerReferences() got = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/main.go b/main.go index b6330b2ef1..62ad926d87 100644 --- a/main.go +++ b/main.go @@ -424,7 +424,7 @@ func main() { } if cfg.PrometheusCRAvailability() == prometheus.Available { - operatorMetrics, opError := operatormetrics.NewOperatorMetrics(mgr.GetConfig(), scheme) + operatorMetrics, opError := operatormetrics.NewOperatorMetrics(mgr.GetConfig(), scheme, ctrl.Log.WithName("operator-metrics-sm")) if opError != nil { setupLog.Error(opError, "Failed to create the operator metrics SM") } diff --git a/tests/e2e-instrumentation/instrumentation-nginx-contnr-secctx/01-install-app.yaml b/tests/e2e-instrumentation/instrumentation-nginx-contnr-secctx/01-install-app.yaml index eea887ae21..d1ae0e239f 100644 --- a/tests/e2e-instrumentation/instrumentation-nginx-contnr-secctx/01-install-app.yaml +++ b/tests/e2e-instrumentation/instrumentation-nginx-contnr-secctx/01-install-app.yaml @@ -22,7 +22,6 @@ spec: securityContext: runAsUser: 1000 runAsGroup: 3000 - fsGroup: 3000 ports: - containerPort: 8765 env: @@ -33,7 +32,6 @@ spec: mountPath: /etc/nginx/nginx.conf subPath: nginx.conf readOnly: true - imagePullPolicy: Always resources: limits: cpu: "1" diff --git a/tests/e2e-instrumentation/instrumentation-nginx-multicontainer/01-install-app.yaml b/tests/e2e-instrumentation/instrumentation-nginx-multicontainer/01-install-app.yaml index 523a44efcf..3a50ecd54d 100644 --- a/tests/e2e-instrumentation/instrumentation-nginx-multicontainer/01-install-app.yaml +++ b/tests/e2e-instrumentation/instrumentation-nginx-multicontainer/01-install-app.yaml @@ -28,7 +28,6 @@ spec: securityContext: runAsUser: 1000 runAsGroup: 3000 - fsGroup: 3000 runAsNonRoot: true allowPrivilegeEscalation: false seccompProfile: @@ -57,7 +56,6 @@ spec: securityContext: runAsUser: 1000 runAsGroup: 3000 - fsGroup: 3000 runAsNonRoot: true seccompProfile: type: RuntimeDefault diff --git a/tests/e2e-instrumentation/instrumentation-nginx-multicontainer/02-install-app.yaml b/tests/e2e-instrumentation/instrumentation-nginx-multicontainer/02-install-app.yaml index ab80a2db5a..0f2b3a828b 100644 --- a/tests/e2e-instrumentation/instrumentation-nginx-multicontainer/02-install-app.yaml +++ b/tests/e2e-instrumentation/instrumentation-nginx-multicontainer/02-install-app.yaml @@ -28,7 +28,6 @@ spec: securityContext: runAsUser: 1000 runAsGroup: 3000 - fsGroup: 3000 runAsNonRoot: true allowPrivilegeEscalation: false seccompProfile: @@ -45,7 +44,6 @@ spec: mountPath: /etc/nginx/nginx.conf subPath: nginx.conf readOnly: true - imagePullPolicy: Always resources: limits: cpu: 500m @@ -58,7 +56,6 @@ spec: securityContext: runAsUser: 1000 runAsGroup: 3000 - fsGroup: 3000 runAsNonRoot: true seccompProfile: type: RuntimeDefault diff --git a/tests/e2e-instrumentation/instrumentation-nodejs-volume/01-assert.yaml b/tests/e2e-instrumentation/instrumentation-nodejs-volume/01-assert.yaml index 227a175150..83e32efc3a 100644 --- a/tests/e2e-instrumentation/instrumentation-nodejs-volume/01-assert.yaml +++ b/tests/e2e-instrumentation/instrumentation-nodejs-volume/01-assert.yaml @@ -54,8 +54,6 @@ spec: - name: OTEL_RESOURCE_ATTRIBUTES name: myapp volumeMounts: - - mountPath: /var/run/secrets/kubernetes.io/serviceaccount - readOnly: true - mountPath: /otel-auto-instrumentation-nodejs name: opentelemetry-auto-instrumentation-nodejs - args: @@ -64,8 +62,6 @@ spec: initContainers: - name: opentelemetry-auto-instrumentation-nodejs volumes: - - projected: - defaultMode: 420 - name: opentelemetry-auto-instrumentation-nodejs ephemeral: volumeClaimTemplate: diff --git a/tests/e2e-instrumentation/instrumentation-nodejs-volume/01-install-app.yaml b/tests/e2e-instrumentation/instrumentation-nodejs-volume/01-install-app.yaml index f92dc1491b..b219006dfc 100644 --- a/tests/e2e-instrumentation/instrumentation-nodejs-volume/01-install-app.yaml +++ b/tests/e2e-instrumentation/instrumentation-nodejs-volume/01-install-app.yaml @@ -29,4 +29,4 @@ spec: env: - name: NODE_PATH value: /usr/local/lib/node_modules - automountServiceAccountToken: false + automountServiceAccountToken: false diff --git a/tests/e2e-openshift/monitoring/03-assert.yaml b/tests/e2e-openshift/monitoring/03-assert.yaml index 508687915c..813b944fac 100644 --- a/tests/e2e-openshift/monitoring/03-assert.yaml +++ b/tests/e2e-openshift/monitoring/03-assert.yaml @@ -11,6 +11,7 @@ rules: - get - list - watch + - create --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding diff --git a/tests/e2e-openshift/monitoring/03-create-monitoring-roles.yaml b/tests/e2e-openshift/monitoring/03-create-monitoring-roles.yaml index 23fd47841f..dd239ec224 100644 --- a/tests/e2e-openshift/monitoring/03-create-monitoring-roles.yaml +++ b/tests/e2e-openshift/monitoring/03-create-monitoring-roles.yaml @@ -6,7 +6,7 @@ metadata: rules: - apiGroups: ["monitoring.coreos.com"] resources: ["prometheuses/api"] - verbs: ["get", "list", "watch"] + verbs: ["get", "list", "watch", "create"] --- apiVersion: rbac.authorization.k8s.io/v1 diff --git a/tests/e2e-openshift/monitoring/check_metrics.sh b/tests/e2e-openshift/monitoring/check_metrics.sh index 8dd65fc4e0..ad8843ae38 100755 --- a/tests/e2e-openshift/monitoring/check_metrics.sh +++ b/tests/e2e-openshift/monitoring/check_metrics.sh @@ -3,23 +3,23 @@ TOKEN=$(oc create token prometheus-user-workload -n openshift-user-workload-monitoring) THANOS_QUERIER_HOST=$(oc get route thanos-querier -n openshift-monitoring -o json | jq -r '.spec.host') -#Check metrics for OpenTelemetry collector instance. -metrics="otelcol_process_uptime otelcol_process_runtime_total_sys_memory_bytes otelcol_process_memory_rss otelcol_exporter_sent_spans otelcol_process_cpu_seconds otelcol_process_memory_rss otelcol_process_runtime_heap_alloc_bytes otelcol_process_runtime_total_alloc_bytes otelcol_process_runtime_total_sys_memory_bytes otelcol_process_uptime otelcol_receiver_accepted_spans otelcol_receiver_refused_spans opentelemetry_collector_info opentelemetry_collector_exporters opentelemetry_collector_receivers" +# Check metrics for OpenTelemetry collector instance. +metrics="otelcol_process_uptime otelcol_process_runtime_total_sys_memory_bytes otelcol_process_memory_rss otelcol_exporter_sent_spans otelcol_process_cpu_seconds otelcol_process_memory_rss otelcol_process_runtime_heap_alloc_bytes otelcol_process_runtime_total_alloc_bytes otelcol_process_runtime_total_sys_memory_bytes otelcol_process_uptime otelcol_receiver_accepted_spans otelcol_receiver_refused_spans controller_runtime_reconcile_time_seconds_count{controller=\"opentelemetrycollector\"} controller_runtime_reconcile_total{controller=\"opentelemetrycollector\",result=\"success\"} workqueue_work_duration_seconds_count{controller=\"opentelemetrycollector\",name=\"opentelemetrycollector\"}" for metric in $metrics; do -query="$metric" -count=0 + query="$metric" + count=0 -# Keep fetching and checking the metrics until metrics with value is present. -while [[ $count -eq 0 ]]; do - response=$(curl -k -H "Authorization: Bearer $TOKEN" -H "Content-type: application/json" "https://$THANOS_QUERIER_HOST/api/v1/query?query=$query") - count=$(echo "$response" | jq -r '.data.result | length') + # Keep fetching and checking the metrics until metrics with value is present. + while [[ $count -eq 0 ]]; do + response=$(curl -k -H "Authorization: Bearer $TOKEN" --data-urlencode "query=$query" "https://$THANOS_QUERIER_HOST/api/v1/query") + count=$(echo "$response" | jq -r '.data.result | length' | tr -d '\n' | tr -d ' ') - if [[ $count -eq 0 ]]; then - echo "No metric '$metric' with value present. Retrying..." - sleep 5 # Wait for 5 seconds before retrying + if [[ "$count" -eq 0 ]]; then + echo "No metric '$metric' with value present. Retrying..." + sleep 5 # Wait for 5 seconds before retrying else - echo "Metric '$metric' with value is present." + echo "Metric '$metric' with value is present." fi done done diff --git a/tests/e2e-targetallocator/targetallocator-features/00-install.yaml b/tests/e2e-targetallocator/targetallocator-features/00-install.yaml index 26eed14f12..9213d607a4 100644 --- a/tests/e2e-targetallocator/targetallocator-features/00-install.yaml +++ b/tests/e2e-targetallocator/targetallocator-features/00-install.yaml @@ -93,7 +93,6 @@ spec: runAsUser: 1000 prometheusCR: enabled: true - filterStrategy: "" securityContext: capabilities: add: