Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
### Added

- Add support for the `aws.ec2` resource detector in `go.opentelemetry.io/contrib/otelconf/x`. (#9139)
- Add `go.opentelemetry.io/contrib/detectors/kubeadm`, a new resource detector for kubeadm-provisioned Kubernetes clusters, ported from `processor/resourcedetectionprocessor/internal/kubeadm` in `opentelemetry-collector-contrib`. Detects `k8s.cluster.name` from the `ClusterConfiguration` document in the `kube-system/kubeadm-config` ConfigMap and `k8s.cluster.uid` from the `kube-system` namespace UID. (#9500)

### Fixed

Expand Down
1 change: 1 addition & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ detectors/gcp/ @open-te
detectors/hetzner/ @open-telemetry/go-approvers @paulojmdias
detectors/ibmcloud/vpc/ @open-telemetry/go-approvers @paulojmdias @iblancasa
detectors/k8sapi/ @open-telemetry/go-approvers @paulojmdias @iblancasa @dashpole
detectors/kubeadm/ @open-telemetry/go-approvers @paulojmdias
detectors/vultr/ @open-telemetry/go-approvers @paulojmdias @iblancasa

exporters/autoexport @open-telemetry/go-approvers @MikeGoldsmith @pellared
Expand Down
7 changes: 7 additions & 0 deletions detectors/autodetect/autodetect.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"go.opentelemetry.io/contrib/detectors/hetzner"
"go.opentelemetry.io/contrib/detectors/ibmcloud/vpc"
"go.opentelemetry.io/contrib/detectors/k8sapi"
"go.opentelemetry.io/contrib/detectors/kubeadm"
"go.opentelemetry.io/contrib/detectors/vultr"
)

Expand Down Expand Up @@ -73,6 +74,10 @@ var (
// attributes from the Kubernetes API (see k8sapi.NewResourceDetector for
// details).
IDK8sAPI = ID("k8sapi")
// IDKubeadm is the ID for the kubeadm detector that detects resource
// attributes of the kubeadm-provisioned Kubernetes cluster the process is
// running in (see kubeadm.NewResourceDetector for details).
IDKubeadm = ID("kubeadm")
// IDVultr is the ID for the Vultr detector that detects resource attributes
// on Vultr Cloud Compute instances (see vultr.NewResourceDetector for
// details).
Expand Down Expand Up @@ -168,6 +173,8 @@ var (

IDK8sAPI: func() resource.Detector { return k8sapi.NewResourceDetector() },

IDKubeadm: func() resource.Detector { return kubeadm.NewResourceDetector() },

IDVultr: func() resource.Detector { return vultr.NewResourceDetector() },

IDHost: optFactory(resource.WithHost()),
Expand Down
15 changes: 15 additions & 0 deletions detectors/autodetect/autodetect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,21 @@ func TestIBMCloudVPCDetectorRegistered(t *testing.T) {
}
}

func TestKubeadmDetectorRegistered(t *testing.T) {
detector, err := Detector(IDKubeadm)
if err != nil {
t.Fatalf("got error: %v, expected no error", err)
}

c, ok := detector.(*composite)
if !ok {
t.Fatalf("got %T, expected composite detector", detector)
}
if len(c.detectors) != 1 {
t.Fatalf("got %d detectors, expected 1 detector", len(c.detectors))
}
}

func TestOptDetectorDetect(t *testing.T) {
want := attribute.String("key", "value")
opt := resource.WithAttributes(want)
Expand Down
3 changes: 3 additions & 0 deletions detectors/autodetect/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ require (
go.opentelemetry.io/contrib/detectors/hetzner v0.17.0
go.opentelemetry.io/contrib/detectors/ibmcloud/vpc v0.17.0
go.opentelemetry.io/contrib/detectors/k8sapi v0.17.0
go.opentelemetry.io/contrib/detectors/kubeadm v0.17.0
go.opentelemetry.io/contrib/detectors/vultr v0.17.0
go.opentelemetry.io/otel v1.45.0
go.opentelemetry.io/otel/sdk v1.45.0
Expand Down Expand Up @@ -122,3 +123,5 @@ replace go.opentelemetry.io/contrib/detectors/k8sapi => ../k8sapi
replace go.opentelemetry.io/contrib/detectors/vultr => ../vultr

replace go.opentelemetry.io/contrib/detectors/aws/ec2/v2 => ../aws/ec2/v2

replace go.opentelemetry.io/contrib/detectors/kubeadm => ../kubeadm
5 changes: 5 additions & 0 deletions detectors/kubeadm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# kubeadm Resource Detector for Go

<!--[![Go Reference][goref-image]][goref-url]-->
<!--[goref-image]: https://pkg.go.dev/badge/go.opentelemetry.io/contrib/detectors/kubeadm.svg-->
<!--[goref-url]: https://pkg.go.dev/go.opentelemetry.io/contrib/detectors/kubeadm-->
45 changes: 45 additions & 0 deletions detectors/kubeadm/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

/*
Package kubeadm provides a [resource.Detector] which supports detecting
attributes of the [kubeadm]-provisioned Kubernetes cluster the process is
running in.

According to semantic conventions for [k8s] attributes, each of the following
attributes is added if it is available:

- k8s.cluster.name
- k8s.cluster.uid

The cluster name is read from the clusterName field of the ClusterConfiguration
document kubeadm stores in the kubeadm-config ConfigMap of the kube-system
namespace. The cluster UID is derived from the UID of the kube-system namespace
itself.

Detection requires the following RBAC:

rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["kubeadm-config"]
verbs: ["get"]
- apiGroups: [""]
resources: ["namespaces"]
resourceNames: ["kube-system"]
verbs: ["get"]

The detector returns an empty resource and no error when the process is not
running inside a Kubernetes cluster, and when it is running inside a cluster
that was not provisioned with kubeadm. A cluster is considered not to be a
kubeadm cluster when the kubeadm-config ConfigMap does not exist.

The k8s.cluster.uid attribute is derived from the same source as the attribute
of the same name in [go.opentelemetry.io/contrib/detectors/k8sapi]. Using both
detectors together is supported: they report an identical value, so merging
their resources does not conflict.

[kubeadm]: https://kubernetes.io/docs/reference/setup-tools/kubeadm/
[k8s]: https://opentelemetry.io/docs/specs/semconv/resource/k8s/
*/
package kubeadm
28 changes: 28 additions & 0 deletions detectors/kubeadm/example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

package kubeadm_test

import (
"context"
"log"

"go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace"

"go.opentelemetry.io/contrib/detectors/kubeadm"
)

func ExampleNewResourceDetector() {
res, err := resource.New(
context.Background(),
resource.WithDetectors(kubeadm.NewResourceDetector()),
)
if err != nil {
log.Fatal(err)
}

tp := sdktrace.NewTracerProvider(sdktrace.WithResource(res))
_ = tp.Shutdown(context.Background())
// Use tp to create tracers ...
}
65 changes: 65 additions & 0 deletions detectors/kubeadm/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
module go.opentelemetry.io/contrib/detectors/kubeadm

go 1.25.0

require (
github.com/stretchr/testify v1.11.1
go.opentelemetry.io/otel v1.45.0
go.opentelemetry.io/otel/sdk v1.45.0
go.yaml.in/yaml/v3 v3.0.5
k8s.io/api v0.35.0
k8s.io/apimachinery v0.35.0
k8s.io/client-go v0.35.0
)

require (
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/go-restful/v3 v3.13.0 // indirect
github.com/fxamacker/cbor/v2 v2.9.2 // indirect
github.com/go-logr/logr v1.4.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v1.0.0 // indirect
github.com/go-openapi/jsonreference v1.0.0 // indirect
github.com/go-openapi/swag v0.28.0 // indirect
github.com/go-openapi/swag/cmdutils v0.28.0 // indirect
github.com/go-openapi/swag/conv v0.28.0 // indirect
github.com/go-openapi/swag/fileutils v0.28.0 // indirect
github.com/go-openapi/swag/jsonutils v0.28.0 // indirect
github.com/go-openapi/swag/loading v0.28.0 // indirect
github.com/go-openapi/swag/mangling v0.28.0 // indirect
github.com/go-openapi/swag/netutils v0.28.0 // indirect
github.com/go-openapi/swag/pools v0.28.0 // indirect
github.com/go-openapi/swag/stringutils v0.28.0 // indirect
github.com/go-openapi/swag/typeutils v0.28.0 // indirect
github.com/go-openapi/swag/yamlutils v0.28.0 // indirect
github.com/google/gnostic-models v0.7.1 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/otel/metric v1.45.0 // indirect
go.opentelemetry.io/otel/trace v1.45.0 // indirect
go.yaml.in/yaml/v2 v2.4.4 // indirect
golang.org/x/net v0.58.0 // indirect
golang.org/x/oauth2 v0.36.0 // indirect
golang.org/x/sys v0.47.0 // indirect
golang.org/x/term v0.45.0 // indirect
golang.org/x/text v0.41.0 // indirect
golang.org/x/time v0.15.0 // indirect
google.golang.org/protobuf v1.36.12 // indirect
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/klog/v2 v2.140.0 // indirect
k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad // indirect
k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 // indirect
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v6 v6.4.2 // indirect
sigs.k8s.io/yaml v1.6.0 // indirect
)
Loading
Loading