diff --git a/.chloggen/fix_validation-stabilizationWindowSeconds.yaml b/.chloggen/fix_validation-stabilizationWindowSeconds.yaml
new file mode 100755
index 0000000000..b90f0ecbd9
--- /dev/null
+++ b/.chloggen/fix_validation-stabilizationWindowSeconds.yaml
@@ -0,0 +1,18 @@
+# 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: collector-webhook
+
+# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
+note: "Fixed validation of `stabilizationWindowSeconds` in autoscaler behaviour"
+
+# One or more tracking issues related to the change
+issues: [3345]
+
+# (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: |
+ The validation of `stabilizationWindowSeconds` in the `autoscaler.behaviour.scale[Up|Down]` incorrectly rejected 0 as an invalid value.
+ This has been fixed to ensure that the value is validated correctly (should be >=0 and <=3600) and the error messsage has been updated to reflect this.
diff --git a/.chloggen/inst-tls.yaml b/.chloggen/inst-tls.yaml
new file mode 100755
index 0000000000..7347b315ea
--- /dev/null
+++ b/.chloggen/inst-tls.yaml
@@ -0,0 +1,34 @@
+# 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: auto-instrumentation
+
+# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
+note: Add support for specifying exporter TLS certificates in auto-instrumentation.
+
+# One or more tracking issues related to the change
+issues: [3338]
+
+# (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: |
+ Now Instrumentation CR supports specifying TLS certificates for exporter:
+ ```yaml
+ spec:
+ exporter:
+ endpoint: https://otel-collector:4317
+ tls:
+ secretName: otel-tls-certs
+ configMapName: otel-ca-bundle
+ # otel-ca-bundle
+ ca_file: ca.crt
+ # present in otel-tls-certs
+ cert_file: tls.crt
+ # present in otel-tls-certs
+ key_file: tls.key
+ ```
+
+ * Propagating secrets across namespaces can be done with https://github.com/EmberStack/kubernetes-reflector or https://github.com/zakkg3/ClusterSecret
+ * Restarting workloads on certificate renewal can be done with https://github.com/stakater/Reloader or https://github.com/wave-k8s/wave
diff --git a/.chloggen/native_sidecar.yaml b/.chloggen/native_sidecar.yaml
new file mode 100755
index 0000000000..1637381020
--- /dev/null
+++ b/.chloggen/native_sidecar.yaml
@@ -0,0 +1,21 @@
+# 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: collector
+
+# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
+note: Add native sidecar injection behind a feature gate which is disabled by default.
+
+# One or more tracking issues related to the change
+issues: [2376]
+
+# (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: |
+ Native sidecars are supported since Kubernetes version `1.28` and are availabe by default since `1.29`.
+ To use native sidecars on Kubernetes v1.28 make sure the "SidecarContainers" feature gate on kubernetes is enabled.
+ If native sidecars are available, the operator can be advised to use them by adding adding
+ the `--feature-gates=operator.sidecarcontainers.native` to the Operator args.
+ In the future this may will become availabe as deployment mode on the Collector CR. See [#3356](https://github.com/open-telemetry/opentelemetry-operator/issues/3356)
diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml
index 922467d9b0..b762ef419f 100644
--- a/.github/workflows/e2e.yaml
+++ b/.github/workflows/e2e.yaml
@@ -46,6 +46,9 @@ jobs:
setup: "add-operator-arg OPERATOR_ARG='--feature-gates=operator.targetallocator.mtls' add-certmanager-permissions prepare-e2e"
- group: e2e-automatic-rbac
setup: "add-rbac-permissions-to-operator prepare-e2e"
+ - group: e2e-native-sidecar
+ setup: "add-operator-arg OPERATOR_ARG='--feature-gates=operator.sidecarcontainers.native' prepare-e2e"
+ kube-version: "1.29"
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@v4
diff --git a/Makefile b/Makefile
index 2e73d990d9..384a7ea1f7 100644
--- a/Makefile
+++ b/Makefile
@@ -267,6 +267,13 @@ generate: controller-gen
e2e: chainsaw
$(CHAINSAW) test --test-dir ./tests/e2e
+# e2e-native-sidecar
+# NOTE: make sure the k8s featuregate "SidecarContainers" is set to true.
+# NOTE: make sure the operator featuregate "operator.sidecarcontainers.native" is enabled.
+.PHONY: e2e-native-sidecar
+e2e-native-sidecar: chainsaw
+ $(CHAINSAW) test --test-dir ./tests/e2e-native-sidecar
+
# end-to-end-test for testing automatic RBAC creation
.PHONY: e2e-automatic-rbac
e2e-automatic-rbac: chainsaw
diff --git a/apis/v1alpha1/instrumentation_types.go b/apis/v1alpha1/instrumentation_types.go
index 2cccef7d6b..e158402223 100644
--- a/apis/v1alpha1/instrumentation_types.go
+++ b/apis/v1alpha1/instrumentation_types.go
@@ -97,8 +97,37 @@ type Resource struct {
// Exporter defines OTLP exporter configuration.
type Exporter struct {
// Endpoint is address of the collector with OTLP endpoint.
+ // If the endpoint defines https:// scheme TLS has to be specified.
// +optional
Endpoint string `json:"endpoint,omitempty"`
+
+ // TLS defines certificates for TLS.
+ // TLS needs to be enabled by specifying https:// scheme in the Endpoint.
+ TLS *TLS `json:"tls,omitempty"`
+}
+
+// TLS defines TLS configuration for exporter.
+type TLS struct {
+ // SecretName defines secret name that will be used to configure TLS on the exporter.
+ // It is user responsibility to create the secret in the namespace of the workload.
+ // The secret must contain client certificate (Cert) and private key (Key).
+ // The CA certificate might be defined in the secret or in the config map.
+ SecretName string `json:"secretName,omitempty"`
+
+ // ConfigMapName defines configmap name with CA certificate. If it is not defined CA certificate will be
+ // used from the secret defined in SecretName.
+ ConfigMapName string `json:"configMapName,omitempty"`
+
+ // CA defines the key of certificate (e.g. ca.crt) in the configmap map, secret or absolute path to a certificate.
+ // The absolute path can be used when certificate is already present on the workload filesystem e.g.
+ // /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt
+ CA string `json:"ca_file,omitempty"`
+ // Cert defines the key (e.g. tls.crt) of the client certificate in the secret or absolute path to a certificate.
+ // The absolute path can be used when certificate is already present on the workload filesystem.
+ Cert string `json:"cert_file,omitempty"`
+ // Key defines a key (e.g. tls.key) of the private key in the secret or absolute path to a certificate.
+ // The absolute path can be used when certificate is already present on the workload filesystem.
+ Key string `json:"key_file,omitempty"`
}
// Sampler defines sampling configuration.
diff --git a/apis/v1alpha1/instrumentation_webhook.go b/apis/v1alpha1/instrumentation_webhook.go
index 004992f795..3d896b0a10 100644
--- a/apis/v1alpha1/instrumentation_webhook.go
+++ b/apis/v1alpha1/instrumentation_webhook.go
@@ -236,9 +236,31 @@ func (w InstrumentationWebhook) validate(r *Instrumentation) (admission.Warnings
default:
return warnings, fmt.Errorf("spec.sampler.type is not valid: %s", r.Spec.Sampler.Type)
}
+
+ warnings = append(warnings, validateExporter(r.Spec.Exporter)...)
+
return warnings, nil
}
+func validateExporter(exporter Exporter) []string {
+ var warnings []string
+ if exporter.TLS != nil {
+ tls := exporter.TLS
+ if tls.Key != "" && tls.Cert == "" || tls.Cert != "" && tls.Key == "" {
+ warnings = append(warnings, "both exporter.tls.key and exporter.tls.cert mut be set")
+ }
+
+ if !strings.HasPrefix(exporter.Endpoint, "https://") {
+ warnings = append(warnings, "exporter.tls is configured but exporter.endpoint is not enabling TLS with https://")
+ }
+ }
+ if strings.HasPrefix(exporter.Endpoint, "https://") && exporter.TLS == nil {
+ warnings = append(warnings, "exporter is using https:// but exporter.tls is unset")
+ }
+
+ return warnings
+}
+
func validateJaegerRemoteSamplerArgument(argument string) error {
parts := strings.Split(argument, ",")
diff --git a/apis/v1alpha1/instrumentation_webhook_test.go b/apis/v1alpha1/instrumentation_webhook_test.go
index 81049cbc0c..9c6c1ae5c3 100644
--- a/apis/v1alpha1/instrumentation_webhook_test.go
+++ b/apis/v1alpha1/instrumentation_webhook_test.go
@@ -113,6 +113,94 @@ func TestInstrumentationValidatingWebhook(t *testing.T) {
},
},
},
+ {
+ name: "exporter: tls cert set but missing key",
+ inst: Instrumentation{
+ Spec: InstrumentationSpec{
+ Sampler: Sampler{
+ Type: ParentBasedTraceIDRatio,
+ Argument: "0.99",
+ },
+ Exporter: Exporter{
+ Endpoint: "https://collector:4317",
+ TLS: &TLS{
+ Cert: "cert",
+ },
+ },
+ },
+ },
+ warnings: []string{"both exporter.tls.key and exporter.tls.cert mut be set"},
+ },
+ {
+ name: "exporter: tls key set but missing cert",
+ inst: Instrumentation{
+ Spec: InstrumentationSpec{
+ Sampler: Sampler{
+ Type: ParentBasedTraceIDRatio,
+ Argument: "0.99",
+ },
+ Exporter: Exporter{
+ Endpoint: "https://collector:4317",
+ TLS: &TLS{
+ Key: "key",
+ },
+ },
+ },
+ },
+ warnings: []string{"both exporter.tls.key and exporter.tls.cert mut be set"},
+ },
+ {
+ name: "exporter: tls set but using http://",
+ inst: Instrumentation{
+ Spec: InstrumentationSpec{
+ Sampler: Sampler{
+ Type: ParentBasedTraceIDRatio,
+ Argument: "0.99",
+ },
+ Exporter: Exporter{
+ Endpoint: "http://collector:4317",
+ TLS: &TLS{
+ Key: "key",
+ Cert: "cert",
+ },
+ },
+ },
+ },
+ warnings: []string{"exporter.tls is configured but exporter.endpoint is not enabling TLS with https://"},
+ },
+ {
+ name: "exporter: exporter using http://, but the tls is nil",
+ inst: Instrumentation{
+ Spec: InstrumentationSpec{
+ Sampler: Sampler{
+ Type: ParentBasedTraceIDRatio,
+ Argument: "0.99",
+ },
+ Exporter: Exporter{
+ Endpoint: "https://collector:4317",
+ },
+ },
+ },
+ warnings: []string{"exporter is using https:// but exporter.tls is unset"},
+ },
+ {
+ name: "exporter no warning set",
+ inst: Instrumentation{
+ Spec: InstrumentationSpec{
+ Sampler: Sampler{
+ Type: ParentBasedTraceIDRatio,
+ Argument: "0.99",
+ },
+ Exporter: Exporter{
+ Endpoint: "https://collector:4317",
+ TLS: &TLS{
+ Key: "key",
+ Cert: "cert",
+ },
+ },
+ },
+ },
+ },
}
for _, test := range tests {
diff --git a/apis/v1alpha1/zz_generated.deepcopy.go b/apis/v1alpha1/zz_generated.deepcopy.go
index 270c617e17..5bf6ffaf0a 100644
--- a/apis/v1alpha1/zz_generated.deepcopy.go
+++ b/apis/v1alpha1/zz_generated.deepcopy.go
@@ -171,6 +171,11 @@ func (in *DotNet) DeepCopy() *DotNet {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Exporter) DeepCopyInto(out *Exporter) {
*out = *in
+ if in.TLS != nil {
+ in, out := &in.TLS, &out.TLS
+ *out = new(TLS)
+ **out = **in
+ }
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Exporter.
@@ -323,7 +328,7 @@ func (in *InstrumentationList) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *InstrumentationSpec) DeepCopyInto(out *InstrumentationSpec) {
*out = *in
- out.Exporter = in.Exporter
+ in.Exporter.DeepCopyInto(&out.Exporter)
in.Resource.DeepCopyInto(&out.Resource)
if in.Propagators != nil {
in, out := &in.Propagators, &out.Propagators
@@ -1272,6 +1277,21 @@ func (in *ScaleSubresourceStatus) DeepCopy() *ScaleSubresourceStatus {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *TLS) DeepCopyInto(out *TLS) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLS.
+func (in *TLS) DeepCopy() *TLS {
+ if in == nil {
+ return nil
+ }
+ out := new(TLS)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TargetAllocator) DeepCopyInto(out *TargetAllocator) {
*out = *in
diff --git a/apis/v1beta1/collector_webhook.go b/apis/v1beta1/collector_webhook.go
index e79754b4bd..5a6b80a3b9 100644
--- a/apis/v1beta1/collector_webhook.go
+++ b/apis/v1beta1/collector_webhook.go
@@ -385,13 +385,13 @@ func ValidatePorts(ports []PortsSpec) error {
func checkAutoscalerSpec(autoscaler *AutoscalerSpec) error {
if autoscaler.Behavior != nil {
if autoscaler.Behavior.ScaleDown != nil && autoscaler.Behavior.ScaleDown.StabilizationWindowSeconds != nil &&
- *autoscaler.Behavior.ScaleDown.StabilizationWindowSeconds < int32(1) {
- return fmt.Errorf("the OpenTelemetry Spec autoscale configuration is incorrect, scaleDown should be one or more")
+ (*autoscaler.Behavior.ScaleDown.StabilizationWindowSeconds < int32(0) || *autoscaler.Behavior.ScaleDown.StabilizationWindowSeconds > 3600) {
+ return fmt.Errorf("the OpenTelemetry Spec autoscale configuration is incorrect, scaleDown.stabilizationWindowSeconds should be >=0 and <=3600")
}
if autoscaler.Behavior.ScaleUp != nil && autoscaler.Behavior.ScaleUp.StabilizationWindowSeconds != nil &&
- *autoscaler.Behavior.ScaleUp.StabilizationWindowSeconds < int32(1) {
- return fmt.Errorf("the OpenTelemetry Spec autoscale configuration is incorrect, scaleUp should be one or more")
+ (*autoscaler.Behavior.ScaleUp.StabilizationWindowSeconds < int32(0) || *autoscaler.Behavior.ScaleUp.StabilizationWindowSeconds > 3600) {
+ return fmt.Errorf("the OpenTelemetry Spec autoscale configuration is incorrect, scaleUp.stabilizationWindowSeconds should be >=0 and <=3600")
}
}
if autoscaler.TargetCPUUtilization != nil && *autoscaler.TargetCPUUtilization < int32(1) {
diff --git a/apis/v1beta1/collector_webhook_test.go b/apis/v1beta1/collector_webhook_test.go
index 0b6b915486..d6145543f3 100644
--- a/apis/v1beta1/collector_webhook_test.go
+++ b/apis/v1beta1/collector_webhook_test.go
@@ -17,6 +17,7 @@ package v1beta1_test
import (
"context"
"fmt"
+ "math"
"os"
"testing"
@@ -582,6 +583,7 @@ func TestOTELColValidatingWebhook(t *testing.T) {
one := int32(1)
three := int32(3)
five := int32(5)
+ maxInt := int32(math.MaxInt32)
cfg := v1beta1.Config{}
err := yaml.Unmarshal([]byte(cfgYaml), &cfg)
@@ -913,36 +915,68 @@ func TestOTELColValidatingWebhook(t *testing.T) {
expectedErr: "minReplicas should be one or more",
},
{
- name: "invalid autoscaler scale down",
+ name: "invalid autoscaler scale down stablization window - <0",
otelcol: v1beta1.OpenTelemetryCollector{
Spec: v1beta1.OpenTelemetryCollectorSpec{
Autoscaler: &v1beta1.AutoscalerSpec{
MaxReplicas: &three,
Behavior: &autoscalingv2.HorizontalPodAutoscalerBehavior{
ScaleDown: &autoscalingv2.HPAScalingRules{
- StabilizationWindowSeconds: &zero,
+ StabilizationWindowSeconds: &minusOne,
},
},
},
},
},
- expectedErr: "scaleDown should be one or more",
+ expectedErr: "scaleDown.stabilizationWindowSeconds should be >=0 and <=3600",
},
{
- name: "invalid autoscaler scale up",
+ name: "invalid autoscaler scale down stablization window - >3600",
+ otelcol: v1beta1.OpenTelemetryCollector{
+ Spec: v1beta1.OpenTelemetryCollectorSpec{
+ Autoscaler: &v1beta1.AutoscalerSpec{
+ MaxReplicas: &three,
+ Behavior: &autoscalingv2.HorizontalPodAutoscalerBehavior{
+ ScaleDown: &autoscalingv2.HPAScalingRules{
+ StabilizationWindowSeconds: &maxInt,
+ },
+ },
+ },
+ },
+ },
+ expectedErr: "scaleDown.stabilizationWindowSeconds should be >=0 and <=3600",
+ },
+ {
+ name: "invalid autoscaler scale up stablization window - <0",
+ otelcol: v1beta1.OpenTelemetryCollector{
+ Spec: v1beta1.OpenTelemetryCollectorSpec{
+ Autoscaler: &v1beta1.AutoscalerSpec{
+ MaxReplicas: &three,
+ Behavior: &autoscalingv2.HorizontalPodAutoscalerBehavior{
+ ScaleUp: &autoscalingv2.HPAScalingRules{
+ StabilizationWindowSeconds: &minusOne,
+ },
+ },
+ },
+ },
+ },
+ expectedErr: "scaleUp.stabilizationWindowSeconds should be >=0 and <=3600",
+ },
+ {
+ name: "invalid autoscaler scale up stablization window - >3600",
otelcol: v1beta1.OpenTelemetryCollector{
Spec: v1beta1.OpenTelemetryCollectorSpec{
Autoscaler: &v1beta1.AutoscalerSpec{
MaxReplicas: &three,
Behavior: &autoscalingv2.HorizontalPodAutoscalerBehavior{
ScaleUp: &autoscalingv2.HPAScalingRules{
- StabilizationWindowSeconds: &zero,
+ StabilizationWindowSeconds: &maxInt,
},
},
},
},
},
- expectedErr: "scaleUp should be one or more",
+ expectedErr: "scaleUp.stabilizationWindowSeconds should be >=0 and <=3600",
},
{
name: "invalid autoscaler target cpu utilization",
diff --git a/bundle/community/manifests/opentelemetry-operator.clusterserviceversion.yaml b/bundle/community/manifests/opentelemetry-operator.clusterserviceversion.yaml
index 0811d9a12b..25cab56e55 100644
--- a/bundle/community/manifests/opentelemetry-operator.clusterserviceversion.yaml
+++ b/bundle/community/manifests/opentelemetry-operator.clusterserviceversion.yaml
@@ -99,7 +99,7 @@ metadata:
categories: Logging & Tracing,Monitoring
certified: "false"
containerImage: ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator
- createdAt: "2024-10-08T09:52:53Z"
+ createdAt: "2024-10-16T10:10:50Z"
description: Provides the OpenTelemetry components, including the Collector
operators.operatorframework.io/builder: operator-sdk-v1.29.0
operators.operatorframework.io/project_layout: go.kubebuilder.io/v3
@@ -284,7 +284,9 @@ spec:
- ""
resources:
- namespaces
+ - secrets
verbs:
+ - get
- list
- watch
- apiGroups:
diff --git a/bundle/community/manifests/opentelemetry.io_instrumentations.yaml b/bundle/community/manifests/opentelemetry.io_instrumentations.yaml
index 76f050bf0d..7e59a81d68 100644
--- a/bundle/community/manifests/opentelemetry.io_instrumentations.yaml
+++ b/bundle/community/manifests/opentelemetry.io_instrumentations.yaml
@@ -409,6 +409,19 @@ spec:
properties:
endpoint:
type: string
+ tls:
+ properties:
+ ca_file:
+ type: string
+ cert_file:
+ type: string
+ configMapName:
+ type: string
+ key_file:
+ type: string
+ secretName:
+ type: string
+ type: object
type: object
go:
properties:
diff --git a/bundle/openshift/manifests/opentelemetry-operator.clusterserviceversion.yaml b/bundle/openshift/manifests/opentelemetry-operator.clusterserviceversion.yaml
index 24958408c7..f248186c9a 100644
--- a/bundle/openshift/manifests/opentelemetry-operator.clusterserviceversion.yaml
+++ b/bundle/openshift/manifests/opentelemetry-operator.clusterserviceversion.yaml
@@ -99,7 +99,7 @@ metadata:
categories: Logging & Tracing,Monitoring
certified: "false"
containerImage: ghcr.io/open-telemetry/opentelemetry-operator/opentelemetry-operator
- createdAt: "2024-10-08T09:52:57Z"
+ createdAt: "2024-10-16T10:10:50Z"
description: Provides the OpenTelemetry components, including the Collector
operators.operatorframework.io/builder: operator-sdk-v1.29.0
operators.operatorframework.io/project_layout: go.kubebuilder.io/v3
@@ -284,7 +284,9 @@ spec:
- ""
resources:
- namespaces
+ - secrets
verbs:
+ - get
- list
- watch
- apiGroups:
diff --git a/bundle/openshift/manifests/opentelemetry.io_instrumentations.yaml b/bundle/openshift/manifests/opentelemetry.io_instrumentations.yaml
index 76f050bf0d..7e59a81d68 100644
--- a/bundle/openshift/manifests/opentelemetry.io_instrumentations.yaml
+++ b/bundle/openshift/manifests/opentelemetry.io_instrumentations.yaml
@@ -409,6 +409,19 @@ spec:
properties:
endpoint:
type: string
+ tls:
+ properties:
+ ca_file:
+ type: string
+ cert_file:
+ type: string
+ configMapName:
+ type: string
+ key_file:
+ type: string
+ secretName:
+ type: string
+ type: object
type: object
go:
properties:
diff --git a/cmd/otel-allocator/watcher/promOperator_test.go b/cmd/otel-allocator/watcher/promOperator_test.go
index 7bd3f0f443..215579e636 100644
--- a/cmd/otel-allocator/watcher/promOperator_test.go
+++ b/cmd/otel-allocator/watcher/promOperator_test.go
@@ -973,7 +973,7 @@ func TestRateLimit(t *testing.T) {
},
}
events := make(chan Event, 1)
- eventInterval := 5 * time.Millisecond
+ eventInterval := 500 * time.Millisecond
cfg := allocatorconfig.Config{}
w, _ := getTestPrometheusCRWatcher(t, nil, nil, cfg)
@@ -1006,10 +1006,10 @@ func TestRateLimit(t *testing.T) {
default:
return false
}
- }, eventInterval*2, time.Millisecond)
+ }, time.Second*5, eventInterval/10)
// it's difficult to measure the rate precisely
- // what we do, is send two updates, and then assert that the elapsed time is between eventInterval and 3*eventInterval
+ // what we do, is send two updates, and then assert that the elapsed time is at least eventInterval
startTime := time.Now()
_, err = w.kubeMonitoringClient.MonitoringV1().ServiceMonitors("test").Update(context.Background(), serviceMonitor, metav1.UpdateOptions{})
require.NoError(t, err)
@@ -1020,7 +1020,7 @@ func TestRateLimit(t *testing.T) {
default:
return false
}
- }, eventInterval*2, time.Millisecond)
+ }, time.Second*5, eventInterval/10)
_, err = w.kubeMonitoringClient.MonitoringV1().ServiceMonitors("test").Update(context.Background(), serviceMonitor, metav1.UpdateOptions{})
require.NoError(t, err)
require.Eventually(t, func() bool {
@@ -1030,11 +1030,9 @@ func TestRateLimit(t *testing.T) {
default:
return false
}
- }, eventInterval*2, time.Millisecond)
+ }, time.Second*5, eventInterval/10)
elapsedTime := time.Since(startTime)
assert.Less(t, eventInterval, elapsedTime)
- assert.GreaterOrEqual(t, eventInterval*3, elapsedTime)
-
}
// getTestPrometheusCRWatcher creates a test instance of PrometheusCRWatcher with fake clients
diff --git a/config/crd/bases/opentelemetry.io_instrumentations.yaml b/config/crd/bases/opentelemetry.io_instrumentations.yaml
index 19582f62c6..ac7f54d183 100644
--- a/config/crd/bases/opentelemetry.io_instrumentations.yaml
+++ b/config/crd/bases/opentelemetry.io_instrumentations.yaml
@@ -407,6 +407,19 @@ spec:
properties:
endpoint:
type: string
+ tls:
+ properties:
+ ca_file:
+ type: string
+ cert_file:
+ type: string
+ configMapName:
+ type: string
+ key_file:
+ type: string
+ secretName:
+ type: string
+ type: object
type: object
go:
properties:
diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml
index 73632f89c8..0991eb4d38 100644
--- a/config/rbac/role.yaml
+++ b/config/rbac/role.yaml
@@ -30,7 +30,9 @@ rules:
- ""
resources:
- namespaces
+ - secrets
verbs:
+ - get
- list
- watch
- apiGroups:
diff --git a/docs/api.md b/docs/api.md
index 24d16da3f4..dc327344f8 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -1625,7 +1625,80 @@ Exporter defines exporter configuration.
endpoint |
string |
- Endpoint is address of the collector with OTLP endpoint.
+ Endpoint is address of the collector with OTLP endpoint.
+If the endpoint defines https:// scheme TLS has to be specified.
+ |
+ false |
+
+ tls |
+ object |
+
+ TLS defines certificates for TLS.
+TLS needs to be enabled by specifying https:// scheme in the Endpoint.
+ |
+ false |
+
+
+
+
+### Instrumentation.spec.exporter.tls
+[↩ Parent](#instrumentationspecexporter)
+
+
+
+TLS defines certificates for TLS.
+TLS needs to be enabled by specifying https:// scheme in the Endpoint.
+
+
+
+
+ Name |
+ Type |
+ Description |
+ Required |
+
+
+
+ ca_file |
+ string |
+
+ CA defines the key of certificate (e.g. ca.crt) in the configmap map, secret or absolute path to a certificate.
+The absolute path can be used when certificate is already present on the workload filesystem e.g.
+/var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt
+ |
+ false |
+
+ cert_file |
+ string |
+
+ Cert defines the key (e.g. tls.crt) of the client certificate in the secret or absolute path to a certificate.
+The absolute path can be used when certificate is already present on the workload filesystem.
+ |
+ false |
+
+ configMapName |
+ string |
+
+ ConfigMapName defines configmap name with CA certificate. If it is not defined CA certificate will be
+used from the secret defined in SecretName.
+ |
+ false |
+
+ key_file |
+ string |
+
+ Key defines a key (e.g. tls.key) of the private key in the secret or absolute path to a certificate.
+The absolute path can be used when certificate is already present on the workload filesystem.
+ |
+ false |
+
+ secretName |
+ string |
+
+ SecretName defines secret name that will be used to configure TLS on the exporter.
+It is user responsibility to create the secret in the namespace of the workload.
+The secret must contain client certificate (Cert) and private key (Key).
+The CA certificate might be defined in the secret or in the config map.
|
false |
diff --git a/go.mod b/go.mod
index c29aafe2a5..1246d868d7 100644
--- a/go.mod
+++ b/go.mod
@@ -32,12 +32,12 @@ require (
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.9.0
go.opentelemetry.io/collector/featuregate v1.17.0
- go.opentelemetry.io/otel v1.30.0
- go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.30.0
- go.opentelemetry.io/otel/exporters/prometheus v0.52.0
- go.opentelemetry.io/otel/metric v1.30.0
- go.opentelemetry.io/otel/sdk v1.30.0
- go.opentelemetry.io/otel/sdk/metric v1.30.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.uber.org/multierr v1.11.0
go.uber.org/zap v1.27.0
gopkg.in/yaml.v2 v2.4.0
@@ -49,17 +49,17 @@ require (
k8s.io/component-base v0.31.1
k8s.io/klog/v2 v2.130.1
k8s.io/kubectl v0.31.1
- k8s.io/utils v0.0.0-20240711033017-18e509b52bc8
+ k8s.io/utils v0.0.0-20240921022957-49e7df575cb6
sigs.k8s.io/controller-runtime v0.19.0
- sigs.k8s.io/gateway-api v1.0.0 // indirect
+ sigs.k8s.io/gateway-api v1.1.0 // indirect
sigs.k8s.io/yaml v1.4.0
)
require (
- cloud.google.com/go/auth v0.7.0 // indirect
- cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect
- cloud.google.com/go/compute/metadata v0.4.0 // indirect
- github.com/Azure/azure-sdk-for-go/sdk/azcore v1.13.0 // indirect
+ cloud.google.com/go/auth v0.9.4 // indirect
+ cloud.google.com/go/auth/oauth2adapt v0.2.4 // indirect
+ cloud.google.com/go/compute/metadata v0.5.1 // indirect
+ github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0 // indirect
@@ -75,13 +75,13 @@ require (
github.com/bytedance/sonic v1.11.6 // indirect
github.com/bytedance/sonic/loader v0.1.1 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
- github.com/cert-manager/cert-manager v1.14.5
+ github.com/cert-manager/cert-manager v1.16.1
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
- github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b // indirect
+ github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dennwc/varint v1.0.0 // indirect
- github.com/digitalocean/godo v1.118.0 // indirect
+ github.com/digitalocean/godo v1.125.0 // indirect
github.com/distribution/reference v0.6.0 // indirect
github.com/docker/docker v27.1.1+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
@@ -89,8 +89,8 @@ require (
github.com/edsrzf/mmap-go v1.1.0 // indirect
github.com/efficientgo/core v1.0.0-rc.2 // indirect
github.com/emicklei/go-restful/v3 v3.12.1 // indirect
- github.com/envoyproxy/go-control-plane v0.12.1-0.20240621013728-1eb8caab5155 // indirect
- github.com/envoyproxy/protoc-gen-validate v1.0.4 // indirect
+ github.com/envoyproxy/go-control-plane v0.13.0 // indirect
+ github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb // indirect
github.com/fatih/color v1.16.0 // indirect
@@ -127,9 +127,9 @@ require (
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
- github.com/google/s2a-go v0.1.7 // indirect
- github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
- github.com/googleapis/gax-go/v2 v2.12.5 // indirect
+ github.com/google/s2a-go v0.1.8 // indirect
+ github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect
+ github.com/googleapis/gax-go/v2 v2.13.0 // indirect
github.com/gophercloud/gophercloud v1.13.0 // indirect
github.com/gorilla/websocket v1.5.1 // indirect
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect
@@ -164,7 +164,7 @@ require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/metalmatze/signal v0.0.0-20210307161603-1c9aa721a97a // indirect
- github.com/miekg/dns v1.1.61 // indirect
+ github.com/miekg/dns v1.1.62 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
@@ -199,32 +199,32 @@ require (
github.com/yusufpapurcu/wmi v1.2.3 // indirect
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.53.0 // indirect
- go.opentelemetry.io/otel/trace v1.30.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/proto/otlp v1.3.1 // indirect
go.uber.org/atomic v1.11.0 // indirect
golang.org/x/arch v0.8.0 // indirect
- golang.org/x/crypto v0.27.0 // indirect
+ golang.org/x/crypto v0.28.0 // indirect
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect
golang.org/x/mod v0.20.0 // indirect
- golang.org/x/net v0.29.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.25.0 // indirect
- golang.org/x/term v0.24.0 // indirect
- golang.org/x/text v0.18.0 // indirect
+ golang.org/x/sys v0.26.0 // indirect
+ golang.org/x/term v0.25.0 // indirect
+ golang.org/x/text v0.19.0 // indirect
golang.org/x/time v0.6.0 // indirect
golang.org/x/tools v0.24.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
- google.golang.org/api v0.188.0 // indirect
- google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
- google.golang.org/grpc v1.66.1 // indirect
- google.golang.org/protobuf v1.34.2 // 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/grpc v1.67.1 // indirect
+ google.golang.org/protobuf v1.35.1 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
- k8s.io/kube-openapi v0.0.0-20240808142205-8e686545bdb8 // indirect
+ k8s.io/kube-openapi v0.0.0-20240903163716-9e1beecbcb38 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
)
diff --git a/go.sum b/go.sum
index 66953b8fe6..67a6e88500 100644
--- a/go.sum
+++ b/go.sum
@@ -13,18 +13,18 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
-cloud.google.com/go/auth v0.7.0 h1:kf/x9B3WTbBUHkC+1VS8wwwli9TzhSt0vSTVBmMR8Ts=
-cloud.google.com/go/auth v0.7.0/go.mod h1:D+WqdrpcjmiCgWrXmLLxOVq1GACoE36chW6KXoEvuIw=
-cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4=
-cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q=
+cloud.google.com/go/auth v0.9.4 h1:DxF7imbEbiFu9+zdKC6cKBko1e8XeJnipNqIbWZ+kDI=
+cloud.google.com/go/auth v0.9.4/go.mod h1:SHia8n6//Ya940F1rLimhJCjjx7KE17t0ctFEci3HkA=
+cloud.google.com/go/auth/oauth2adapt v0.2.4 h1:0GWE/FUsXhf6C+jAkWgYm7X9tK8cuEIfy19DBn6B6bY=
+cloud.google.com/go/auth/oauth2adapt v0.2.4/go.mod h1:jC/jOpwFP6JBxhB3P5Rr0a9HLMC/Pe3eaL4NmdvqPtc=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
-cloud.google.com/go/compute/metadata v0.4.0 h1:vHzJCWaM4g8XIcm8kopr3XmDA4Gy/lblD3EhhSux05c=
-cloud.google.com/go/compute/metadata v0.4.0/go.mod h1:SIQh1Kkb4ZJ8zJ874fqVkslA29PRXuleyj6vOzlbK7M=
+cloud.google.com/go/compute/metadata v0.5.1 h1:NM6oZeZNlYjiwYje+sYFjEpP0Q0zCan1bmQW/KmIrGs=
+cloud.google.com/go/compute/metadata v0.5.1/go.mod h1:C66sj2AluDcIqakBq/M8lw8/ybHgOZqin2obFxa/E5k=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
@@ -39,8 +39,8 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
-github.com/Azure/azure-sdk-for-go/sdk/azcore v1.13.0 h1:GJHeeA2N7xrG3q30L2UXDyuWRzDM900/65j70wcM4Ww=
-github.com/Azure/azure-sdk-for-go/sdk/azcore v1.13.0/go.mod h1:l38EPgmsp71HHLq9j7De57JcKOWPyhrsW1Awm1JS6K0=
+github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 h1:nyQWyZvwGTvunIMxi1Y9uXkcyr+I7TeNrr/foo4Kpk8=
+github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0/go.mod h1:l38EPgmsp71HHLq9j7De57JcKOWPyhrsW1Awm1JS6K0=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 h1:tfLQ34V6F7tVSwoTf/4lH5sE0o6eCJuNDTmH09nDpbc=
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY=
@@ -103,8 +103,8 @@ github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
-github.com/cert-manager/cert-manager v1.14.5 h1:uuM1O2g2S80nxiH3eW2cZYMGiL2zmDFVdAzg8sibWuc=
-github.com/cert-manager/cert-manager v1.14.5/go.mod h1:fmr/cU5jiLxWj69CroDggSOa49RljUK+dU583TaQUXM=
+github.com/cert-manager/cert-manager v1.16.1 h1:1ceFMqTtwiqY2vyfaRT85CNiVmK7pJjt3GebYCx9awY=
+github.com/cert-manager/cert-manager v1.16.1/go.mod h1:MfLVTL45hFZsqmaT1O0+b2ugaNNQQZttSFV9hASHUb0=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
@@ -119,8 +119,8 @@ github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJ
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
-github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b h1:ga8SEFjZ60pxLcmhnThWgvH2wg8376yUJmPhEH4H3kw=
-github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
+github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20 h1:N+3sFI5GUjRKBi+i0TxYVST9h4Ie192jJWpHvthBBgg=
+github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
@@ -130,8 +130,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE=
github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA=
-github.com/digitalocean/godo v1.118.0 h1:lkzGFQmACrVCp7UqH1sAi4JK/PWwlc5aaxubgorKmC4=
-github.com/digitalocean/godo v1.118.0/go.mod h1:Vk0vpCot2HOAJwc5WE8wljZGtJ3ZtWIc8MQ8rF38sdo=
+github.com/digitalocean/godo v1.125.0 h1:wGPBQRX9Wjo0qCF0o8d25mT3A84Iw8rfHnZOPyvHcMQ=
+github.com/digitalocean/godo v1.125.0/go.mod h1:PU8JB6I1XYkQIdHFop8lLAY9ojp6M0XcU0TWaQSxbrc=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
@@ -151,11 +151,11 @@ github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRr
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
-github.com/envoyproxy/go-control-plane v0.12.1-0.20240621013728-1eb8caab5155 h1:IgJPqnrlY2Mr4pYB6oaMKvFvwJ9H+X6CCY5x1vCTcpc=
-github.com/envoyproxy/go-control-plane v0.12.1-0.20240621013728-1eb8caab5155/go.mod h1:5Wkq+JduFtdAXihLmeTJf+tRYIT4KBc2vPXDhwVo1pA=
+github.com/envoyproxy/go-control-plane v0.13.0 h1:HzkeUz1Knt+3bK+8LG1bxOO/jzWZmdxpwC51i202les=
+github.com/envoyproxy/go-control-plane v0.13.0/go.mod h1:GRaKG3dwvFoTg4nj7aXdZnvMg4d7nvT/wl9WgVXn3Q8=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A=
-github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew=
+github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM=
+github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4=
github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls=
github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg=
@@ -313,17 +313,17 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k=
github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
-github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
+github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM=
+github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs=
-github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
+github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw=
+github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
-github.com/googleapis/gax-go/v2 v2.12.5 h1:8gw9KZK8TiVKB6q3zHY3SBzLnrGp6HQjyfYBYGmXdxA=
-github.com/googleapis/gax-go/v2 v2.12.5/go.mod h1:BUDKcWo+RaKq5SC9vVYL0wLADa3VcfswbOMMRmB9H3E=
+github.com/googleapis/gax-go/v2 v2.13.0 h1:yitjD5f7jQHhyDsnhKEBU52NdvvdSeGzlAnDPT0hH1s=
+github.com/googleapis/gax-go/v2 v2.13.0/go.mod h1:Z/fvTZXF8/uw7Xu5GuslPw+bplx6SS338j1Is2S+B7A=
github.com/gophercloud/gophercloud v1.13.0 h1:8iY9d1DAbzMW6Vok1AxbbK5ZaUjzMp0tdyt4fX9IeJ0=
github.com/gophercloud/gophercloud v1.13.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM=
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
@@ -465,8 +465,8 @@ github.com/metalmatze/signal v0.0.0-20210307161603-1c9aa721a97a h1:0usWxe5SGXKQo
github.com/metalmatze/signal v0.0.0-20210307161603-1c9aa721a97a/go.mod h1:3OETvrxfELvGsU2RoGGWercfeZ4bCL3+SOwzIWtJH/Q=
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
-github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs=
-github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ=
+github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ=
+github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ=
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
@@ -578,8 +578,8 @@ github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoG
github.com/prometheus/prometheus v0.54.1 h1:vKuwQNjnYN2/mDoWfHXDhAsz/68q/dQDb+YbcEqU7MQ=
github.com/prometheus/prometheus v0.54.1/go.mod h1:xlLByHhk2g3ycakQGrMaU8K7OySZx98BzeCR99991NY=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
-github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
+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=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.29 h1:BkTk4gynLjguayxrYxZoMZjBnAOh7ntQvUkOFmkMqPU=
@@ -648,26 +648,26 @@ 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.17.0 h1:vpfXyWe7DFqCsDArsR9rAKKtVpt72PKjzjeqPegViws=
go.opentelemetry.io/collector/featuregate v1.17.0/go.mod h1:47xrISO71vJ83LSMm8+yIDsUbKktUp48Ovt7RR6VbRs=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg=
-go.opentelemetry.io/otel v1.30.0 h1:F2t8sK4qf1fAmY9ua4ohFS/K+FUuOPemHUIXHtktrts=
-go.opentelemetry.io/otel v1.30.0/go.mod h1:tFw4Br9b7fOS+uEao81PJjVMjW/5fvNCbpsDIXqP0pc=
-go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.30.0 h1:VrMAbeJz4gnVDg2zEzjHG4dEH86j4jO6VYB+NgtGD8s=
-go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.30.0/go.mod h1:qqN/uFdpeitTvm+JDqqnjm517pmQRYxTORbETHq5tOc=
+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/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 h1:j9+03ymgYhPKmeXGk5Zu+cIZOlVzd9Zv7QIiyItjFBU=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0/go.mod h1:Y5+XiUG4Emn1hTfciPzGPJaSI+RpDts6BnCIir0SLqk=
-go.opentelemetry.io/otel/exporters/prometheus v0.52.0 h1:kmU3H0b9ufFSi8IQCcxack+sWUblKkFbqWYs6YiACGQ=
-go.opentelemetry.io/otel/exporters/prometheus v0.52.0/go.mod h1:+wsAp2+JhuGXX7YRkjlkx6hyWY3ogFPfNA4x3nyiAh0=
-go.opentelemetry.io/otel/metric v1.30.0 h1:4xNulvn9gjzo4hjg+wzIKG7iNFEaBMX00Qd4QIZs7+w=
-go.opentelemetry.io/otel/metric v1.30.0/go.mod h1:aXTfST94tswhWEb+5QjlSqG+cZlmyXy/u8jFpor3WqQ=
-go.opentelemetry.io/otel/sdk v1.30.0 h1:cHdik6irO49R5IysVhdn8oaiR9m8XluDaJAs4DfOrYE=
-go.opentelemetry.io/otel/sdk v1.30.0/go.mod h1:p14X4Ok8S+sygzblytT1nqG98QG2KYKv++HE0LY/mhg=
-go.opentelemetry.io/otel/sdk/metric v1.30.0 h1:QJLT8Pe11jyHBHfSAgYH7kEmT24eX792jZO1bo4BXkM=
-go.opentelemetry.io/otel/sdk/metric v1.30.0/go.mod h1:waS6P3YqFNzeP01kuo/MBBYqaoBJl7efRQHOaydhy1Y=
-go.opentelemetry.io/otel/trace v1.30.0 h1:7UBkkYzeg3C7kQX8VAidWh2biiQbtAKjyIML8dQ9wmc=
-go.opentelemetry.io/otel/trace v1.30.0/go.mod h1:5EyKqTzzmyqB9bwtCCq6pDLktPK6fmGf/Dph+8VI02o=
+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/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=
@@ -692,8 +692,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
-golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
-golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
+golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
+golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -770,8 +770,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
-golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
-golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
+golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
+golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -855,16 +855,16 @@ 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.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
-golang.org/x/sys v0.25.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/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=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
-golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM=
-golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
+golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
+golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -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.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
-golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
+golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
+golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
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=
@@ -953,8 +953,8 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
-google.golang.org/api v0.188.0 h1:51y8fJ/b1AaaBRJr4yWm96fPcuxSo0JcegXE3DaHQHw=
-google.golang.org/api v0.188.0/go.mod h1:VR0d+2SIiWOYG3r/jdm7adPW9hI2aRv9ETOSCQ9Beag=
+google.golang.org/api v0.198.0 h1:OOH5fZatk57iN0A7tjJQzt6aPfYQ1JiWkt1yGseazks=
+google.golang.org/api v0.198.0/go.mod h1:/Lblzl3/Xqqk9hw/yS97TImKTUwnf1bv89v7+OagJzc=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -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-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc=
-google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
+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/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=
@@ -1007,8 +1007,8 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
-google.golang.org/grpc v1.66.1 h1:hO5qAXR19+/Z44hmvIM4dQFMSYX9XcWsByfoxutBpAM=
-google.golang.org/grpc v1.66.1/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
+google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
+google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -1020,8 +1020,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
-google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
+google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
+google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -1067,12 +1067,12 @@ k8s.io/component-base v0.31.1 h1:UpOepcrX3rQ3ab5NB6g5iP0tvsgJWzxTyAo20sgYSy8=
k8s.io/component-base v0.31.1/go.mod h1:WGeaw7t/kTsqpVTaCoVEtillbqAhF2/JgvO0LDOMa0w=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
-k8s.io/kube-openapi v0.0.0-20240808142205-8e686545bdb8 h1:1Wof1cGQgA5pqgo8MxKPtf+qN6Sh/0JzznmeGPm1HnE=
-k8s.io/kube-openapi v0.0.0-20240808142205-8e686545bdb8/go.mod h1:Os6V6dZwLNii3vxFpxcNaTmH8LJJBkOTg1N0tOA0fvA=
+k8s.io/kube-openapi v0.0.0-20240903163716-9e1beecbcb38 h1:1dWzkmJrrprYvjGwh9kEUxmcUV/CtNU8QM7h1FLWQOo=
+k8s.io/kube-openapi v0.0.0-20240903163716-9e1beecbcb38/go.mod h1:coRQXBK9NxO98XUv3ZD6AK3xzHCxV6+b7lrquKwaKzA=
k8s.io/kubectl v0.31.1 h1:ih4JQJHxsEggFqDJEHSOdJ69ZxZftgeZvYo7M/cpp24=
k8s.io/kubectl v0.31.1/go.mod h1:aNuQoR43W6MLAtXQ/Bu4GDmoHlbhHKuyD49lmTC8eJM=
-k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A=
-k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+k8s.io/utils v0.0.0-20240921022957-49e7df575cb6 h1:MDF6h2H/h4tbzmtIKTuctcwZmY0tY9mD9fNT47QO6HI=
+k8s.io/utils v0.0.0-20240921022957-49e7df575cb6/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
@@ -1080,8 +1080,8 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/controller-runtime v0.19.0 h1:nWVM7aq+Il2ABxwiCizrVDSlmDcshi9llbaFbC0ji/Q=
sigs.k8s.io/controller-runtime v0.19.0/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4=
-sigs.k8s.io/gateway-api v1.0.0 h1:iPTStSv41+d9p0xFydll6d7f7MOBGuqXM6p2/zVYMAs=
-sigs.k8s.io/gateway-api v1.0.0/go.mod h1:4cUgr0Lnp5FZ0Cdq8FdRwCvpiWws7LVhLHGIudLlf4c=
+sigs.k8s.io/gateway-api v1.1.0 h1:DsLDXCi6jR+Xz8/xd0Z1PYl2Pn0TyaFMOPPZIj4inDM=
+sigs.k8s.io/gateway-api v1.1.0/go.mod h1:ZH4lHrL2sDi0FHZ9jjneb8kKnGzFWyrTya35sWUTrRs=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
diff --git a/internal/webhook/podmutation/webhookhandler.go b/internal/webhook/podmutation/webhookhandler.go
index b4ad5fa7fc..a0704c5ad9 100644
--- a/internal/webhook/podmutation/webhookhandler.go
+++ b/internal/webhook/podmutation/webhookhandler.go
@@ -30,7 +30,7 @@ import (
)
// +kubebuilder:webhook:path=/mutate-v1-pod,mutating=true,failurePolicy=ignore,groups="",resources=pods,verbs=create,versions=v1,name=mpod.kb.io,sideEffects=none,admissionReviewVersions=v1
-// +kubebuilder:rbac:groups="",resources=namespaces,verbs=list;watch
+// +kubebuilder:rbac:groups="",resources=namespaces;secrets,verbs=get;list;watch
// +kubebuilder:rbac:groups=opentelemetry.io,resources=opentelemetrycollectors,verbs=get;list;watch
// +kubebuilder:rbac:groups=opentelemetry.io,resources=instrumentations,verbs=get;list;watch
// +kubebuilder:rbac:groups="apps",resources=replicasets,verbs=get;list;watch
diff --git a/pkg/constants/env.go b/pkg/constants/env.go
index 8dd4f65200..8bfcd667f4 100644
--- a/pkg/constants/env.go
+++ b/pkg/constants/env.go
@@ -15,12 +15,16 @@
package constants
const (
- EnvOTELServiceName = "OTEL_SERVICE_NAME"
- EnvOTELExporterOTLPEndpoint = "OTEL_EXPORTER_OTLP_ENDPOINT"
- EnvOTELResourceAttrs = "OTEL_RESOURCE_ATTRIBUTES"
- EnvOTELPropagators = "OTEL_PROPAGATORS"
- EnvOTELTracesSampler = "OTEL_TRACES_SAMPLER"
- EnvOTELTracesSamplerArg = "OTEL_TRACES_SAMPLER_ARG"
+ EnvOTELServiceName = "OTEL_SERVICE_NAME"
+ EnvOTELResourceAttrs = "OTEL_RESOURCE_ATTRIBUTES"
+ EnvOTELPropagators = "OTEL_PROPAGATORS"
+ EnvOTELTracesSampler = "OTEL_TRACES_SAMPLER"
+ EnvOTELTracesSamplerArg = "OTEL_TRACES_SAMPLER_ARG"
+
+ EnvOTELExporterOTLPEndpoint = "OTEL_EXPORTER_OTLP_ENDPOINT"
+ EnvOTELExporterCertificate = "OTEL_EXPORTER_OTLP_CERTIFICATE"
+ EnvOTELExporterClientCertificate = "OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE"
+ EnvOTELExporterClientKey = "OTEL_EXPORTER_OTLP_CLIENT_KEY"
InstrumentationPrefix = "instrumentation.opentelemetry.io/"
AnnotationDefaultAutoInstrumentationJava = InstrumentationPrefix + "default-auto-instrumentation-java-image"
diff --git a/pkg/featuregate/featuregate.go b/pkg/featuregate/featuregate.go
index 5b452da235..0db8286b6e 100644
--- a/pkg/featuregate/featuregate.go
+++ b/pkg/featuregate/featuregate.go
@@ -25,6 +25,18 @@ const (
)
var (
+ // EnableNativeSidecarContainers is the feature gate that controls whether a
+ // sidecar should be injected as a native sidecar or the classic way.
+ // Native sidecar containers have been available since kubernetes v1.28 in
+ // alpha and v1.29 in beta.
+ // It needs to be enabled with +featureGate=SidecarContainers.
+ // See:
+ // https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/#feature-gates-for-alpha-or-beta-features
+ EnableNativeSidecarContainers = featuregate.GlobalRegistry().MustRegister(
+ "operator.sidecarcontainers.native",
+ featuregate.StageAlpha,
+ featuregate.WithRegisterDescription("controls whether the operator supports sidecar containers as init containers. Should only be enabled on k8s v1.29+"),
+ )
// PrometheusOperatorIsAvailable is the feature gate that enables features associated to the Prometheus Operator.
PrometheusOperatorIsAvailable = featuregate.GlobalRegistry().MustRegister(
"operator.observability.prometheus",
diff --git a/pkg/instrumentation/exporter.go b/pkg/instrumentation/exporter.go
new file mode 100644
index 0000000000..5598de24cf
--- /dev/null
+++ b/pkg/instrumentation/exporter.go
@@ -0,0 +1,150 @@
+// Copyright The OpenTelemetry Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package instrumentation
+
+import (
+ "fmt"
+ "path/filepath"
+
+ corev1 "k8s.io/api/core/v1"
+
+ "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1"
+ "github.com/open-telemetry/opentelemetry-operator/internal/naming"
+ "github.com/open-telemetry/opentelemetry-operator/pkg/constants"
+)
+
+func configureExporter(exporter v1alpha1.Exporter, pod *corev1.Pod, container *corev1.Container) {
+ if exporter.Endpoint != "" {
+ if getIndexOfEnv(container.Env, constants.EnvOTELExporterOTLPEndpoint) == -1 {
+ container.Env = append(container.Env, corev1.EnvVar{
+ Name: constants.EnvOTELExporterOTLPEndpoint,
+ Value: exporter.Endpoint,
+ })
+ }
+ }
+ if exporter.TLS == nil {
+ return
+ }
+ // the name cannot be longer than 63 characters
+ secretVolumeName := naming.Truncate("otel-auto-secret-%s", 63, exporter.TLS.SecretName)
+ secretMountPath := fmt.Sprintf("/otel-auto-instrumentation-secret-%s", exporter.TLS.SecretName)
+ configMapVolumeName := naming.Truncate("otel-auto-configmap-%s", 63, exporter.TLS.ConfigMapName)
+ configMapMountPath := fmt.Sprintf("/otel-auto-instrumentation-configmap-%s", exporter.TLS.ConfigMapName)
+
+ if exporter.TLS.CA != "" {
+ mountPath := secretMountPath
+ if exporter.TLS.ConfigMapName != "" {
+ mountPath = configMapMountPath
+ }
+ envVarVal := fmt.Sprintf("%s/%s", mountPath, exporter.TLS.CA)
+ if filepath.IsAbs(exporter.TLS.CA) {
+ envVarVal = exporter.TLS.CA
+ }
+ if getIndexOfEnv(container.Env, constants.EnvOTELExporterCertificate) == -1 {
+ container.Env = append(container.Env, corev1.EnvVar{
+ Name: constants.EnvOTELExporterCertificate,
+ Value: envVarVal,
+ })
+ }
+ }
+ if exporter.TLS.Cert != "" {
+ envVarVal := fmt.Sprintf("%s/%s", secretMountPath, exporter.TLS.Cert)
+ if filepath.IsAbs(exporter.TLS.Cert) {
+ envVarVal = exporter.TLS.Cert
+ }
+ if getIndexOfEnv(container.Env, constants.EnvOTELExporterClientCertificate) == -1 {
+ container.Env = append(container.Env, corev1.EnvVar{
+ Name: constants.EnvOTELExporterClientCertificate,
+ Value: envVarVal,
+ })
+ }
+ }
+ if exporter.TLS.Key != "" {
+ envVarVar := fmt.Sprintf("%s/%s", secretMountPath, exporter.TLS.Key)
+ if filepath.IsAbs(exporter.TLS.Key) {
+ envVarVar = exporter.TLS.Key
+ }
+ if getIndexOfEnv(container.Env, constants.EnvOTELExporterClientKey) == -1 {
+ container.Env = append(container.Env, corev1.EnvVar{
+ Name: constants.EnvOTELExporterClientKey,
+ Value: envVarVar,
+ })
+ }
+ }
+
+ if exporter.TLS.SecretName != "" {
+ addVolume := true
+ for _, vol := range pod.Spec.Volumes {
+ if vol.Name == secretVolumeName {
+ addVolume = false
+ }
+ }
+ if addVolume {
+ pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{
+ Name: secretVolumeName,
+ VolumeSource: corev1.VolumeSource{
+ Secret: &corev1.SecretVolumeSource{
+ SecretName: exporter.TLS.SecretName,
+ },
+ }})
+ }
+ addVolumeMount := true
+ for _, vol := range container.VolumeMounts {
+ if vol.Name == secretVolumeName {
+ addVolumeMount = false
+ }
+ }
+ if addVolumeMount {
+ container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{
+ Name: secretVolumeName,
+ MountPath: secretMountPath,
+ ReadOnly: true,
+ })
+ }
+ }
+
+ if exporter.TLS.ConfigMapName != "" {
+ addVolume := true
+ for _, vol := range pod.Spec.Volumes {
+ if vol.Name == configMapVolumeName {
+ addVolume = false
+ }
+ }
+ if addVolume {
+ pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{
+ Name: configMapVolumeName,
+ VolumeSource: corev1.VolumeSource{
+ ConfigMap: &corev1.ConfigMapVolumeSource{
+ LocalObjectReference: corev1.LocalObjectReference{
+ Name: exporter.TLS.ConfigMapName,
+ },
+ },
+ }})
+ }
+ addVolumeMount := true
+ for _, vol := range container.VolumeMounts {
+ if vol.Name == configMapVolumeName {
+ addVolumeMount = false
+ }
+ }
+ if addVolumeMount {
+ container.VolumeMounts = append(container.VolumeMounts, corev1.VolumeMount{
+ Name: configMapVolumeName,
+ MountPath: configMapMountPath,
+ ReadOnly: true,
+ })
+ }
+ }
+}
diff --git a/pkg/instrumentation/exporter_test.go b/pkg/instrumentation/exporter_test.go
new file mode 100644
index 0000000000..2fddf1264a
--- /dev/null
+++ b/pkg/instrumentation/exporter_test.go
@@ -0,0 +1,209 @@
+// Copyright The OpenTelemetry Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package instrumentation
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ corev1 "k8s.io/api/core/v1"
+
+ "github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1"
+)
+
+func TestExporter(t *testing.T) {
+ tests := []struct {
+ name string
+ exporter v1alpha1.Exporter
+ expected corev1.Pod
+ }{
+ {
+ name: "ca, crt and key from secret",
+ exporter: v1alpha1.Exporter{
+ Endpoint: "https://collector:4318",
+ TLS: &v1alpha1.TLS{
+ SecretName: "my-certs",
+ CA: "ca.crt",
+ Cert: "cert.crt",
+ Key: "key.key",
+ },
+ },
+ expected: corev1.Pod{
+ Spec: corev1.PodSpec{
+ Volumes: []corev1.Volume{
+ {
+ Name: "otel-auto-secret-my-certs",
+ VolumeSource: corev1.VolumeSource{
+ Secret: &corev1.SecretVolumeSource{
+ SecretName: "my-certs",
+ },
+ },
+ },
+ },
+ Containers: []corev1.Container{
+ {
+ VolumeMounts: []corev1.VolumeMount{
+ {
+ Name: "otel-auto-secret-my-certs",
+ ReadOnly: true,
+ MountPath: "/otel-auto-instrumentation-secret-my-certs",
+ },
+ },
+ Env: []corev1.EnvVar{
+ {
+ Name: "OTEL_EXPORTER_OTLP_ENDPOINT",
+ Value: "https://collector:4318",
+ },
+ {
+ Name: "OTEL_EXPORTER_OTLP_CERTIFICATE",
+ Value: "/otel-auto-instrumentation-secret-my-certs/ca.crt",
+ },
+ {
+ Name: "OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE",
+ Value: "/otel-auto-instrumentation-secret-my-certs/cert.crt",
+ },
+ {
+ Name: "OTEL_EXPORTER_OTLP_CLIENT_KEY",
+ Value: "/otel-auto-instrumentation-secret-my-certs/key.key",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ name: "crt and key from secret and ca from configmap",
+ exporter: v1alpha1.Exporter{
+ Endpoint: "https://collector:4318",
+ TLS: &v1alpha1.TLS{
+ SecretName: "my-certs",
+ ConfigMapName: "ca-bundle",
+ CA: "ca.crt",
+ Cert: "cert.crt",
+ Key: "key.key",
+ },
+ },
+ expected: corev1.Pod{
+ Spec: corev1.PodSpec{
+ Volumes: []corev1.Volume{
+ {
+ Name: "otel-auto-secret-my-certs",
+ VolumeSource: corev1.VolumeSource{
+ Secret: &corev1.SecretVolumeSource{
+ SecretName: "my-certs",
+ },
+ },
+ },
+ {
+ Name: "otel-auto-configmap-ca-bundle",
+ VolumeSource: corev1.VolumeSource{
+ ConfigMap: &corev1.ConfigMapVolumeSource{
+ LocalObjectReference: corev1.LocalObjectReference{
+ Name: "ca-bundle",
+ },
+ },
+ },
+ },
+ },
+ Containers: []corev1.Container{
+ {
+ VolumeMounts: []corev1.VolumeMount{
+ {
+ Name: "otel-auto-secret-my-certs",
+ ReadOnly: true,
+ MountPath: "/otel-auto-instrumentation-secret-my-certs",
+ },
+ {
+ Name: "otel-auto-configmap-ca-bundle",
+ ReadOnly: true,
+ MountPath: "/otel-auto-instrumentation-configmap-ca-bundle",
+ },
+ },
+ Env: []corev1.EnvVar{
+ {
+ Name: "OTEL_EXPORTER_OTLP_ENDPOINT",
+ Value: "https://collector:4318",
+ },
+ {
+ Name: "OTEL_EXPORTER_OTLP_CERTIFICATE",
+ Value: "/otel-auto-instrumentation-configmap-ca-bundle/ca.crt",
+ },
+ {
+ Name: "OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE",
+ Value: "/otel-auto-instrumentation-secret-my-certs/cert.crt",
+ },
+ {
+ Name: "OTEL_EXPORTER_OTLP_CLIENT_KEY",
+ Value: "/otel-auto-instrumentation-secret-my-certs/key.key",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ name: "ca, crt key absolute paths",
+ exporter: v1alpha1.Exporter{
+ Endpoint: "https://collector:4318",
+ TLS: &v1alpha1.TLS{
+ CA: "/ca.crt",
+ Cert: "/cert.crt",
+ Key: "/key.key",
+ },
+ },
+ expected: corev1.Pod{
+ Spec: corev1.PodSpec{
+ Containers: []corev1.Container{
+ {
+ Env: []corev1.EnvVar{
+ {
+ Name: "OTEL_EXPORTER_OTLP_ENDPOINT",
+ Value: "https://collector:4318",
+ },
+ {
+ Name: "OTEL_EXPORTER_OTLP_CERTIFICATE",
+ Value: "/ca.crt",
+ },
+ {
+ Name: "OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE",
+ Value: "/cert.crt",
+ },
+ {
+ Name: "OTEL_EXPORTER_OTLP_CLIENT_KEY",
+ Value: "/key.key",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ }
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ pod := corev1.Pod{
+ Spec: corev1.PodSpec{
+ Containers: []corev1.Container{
+ {},
+ },
+ },
+ }
+ configureExporter(test.exporter, &pod, &pod.Spec.Containers[0])
+ assert.Equal(t, test.expected, pod)
+ })
+ }
+}
diff --git a/pkg/instrumentation/podmutator.go b/pkg/instrumentation/podmutator.go
index b1a2356d04..3c3a2f8e52 100644
--- a/pkg/instrumentation/podmutator.go
+++ b/pkg/instrumentation/podmutator.go
@@ -22,6 +22,7 @@ import (
"github.com/go-logr/logr"
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/types"
"k8s.io/client-go/tools/record"
@@ -395,6 +396,11 @@ func (pm *instPodMutator) Mutate(ctx context.Context, ns corev1.Namespace, pod c
return pod, err
}
+ if err = pm.validateInstrumentations(ctx, insts, ns.Name); err != nil {
+ logger.Error(err, "failed to validate instrumentations")
+ return pod, err
+ }
+
// We retrieve the annotation for podname
if pm.config.EnableMultiInstrumentation() {
err = insts.setLanguageSpecificContainers(ns.ObjectMeta, pod.ObjectMeta)
@@ -460,3 +466,55 @@ func (pm *instPodMutator) selectInstrumentationInstanceFromNamespace(ctx context
return &otelInsts.Items[0], nil
}
}
+
+func (pm *instPodMutator) validateInstrumentations(ctx context.Context, inst languageInstrumentations, podNamespace string) error {
+ instrumentations := []struct {
+ instrumentation *v1alpha1.Instrumentation
+ }{
+ {inst.Java.Instrumentation},
+ {inst.Python.Instrumentation},
+ {inst.NodeJS.Instrumentation},
+ {inst.DotNet.Instrumentation},
+ {inst.Go.Instrumentation},
+ {inst.ApacheHttpd.Instrumentation},
+ {inst.Nginx.Instrumentation},
+ {inst.Sdk.Instrumentation},
+ }
+ var errs []error
+ for _, i := range instrumentations {
+ if i.instrumentation != nil {
+ if err := pm.validateInstrumentation(ctx, i.instrumentation, podNamespace); err != nil {
+ errs = append(errs, err)
+ }
+ }
+ }
+
+ if len(errs) > 0 {
+ return errors.Join(errs...)
+ }
+ return nil
+}
+
+func (pm *instPodMutator) validateInstrumentation(ctx context.Context, inst *v1alpha1.Instrumentation, podNamespace string) error {
+ // Check if secret and configmap exists
+ // If they don't exist pod cannot start
+ var errs []error
+ if inst.Spec.Exporter.TLS != nil {
+ if inst.Spec.Exporter.TLS.SecretName != "" {
+ nsn := types.NamespacedName{Name: inst.Spec.Exporter.TLS.SecretName, Namespace: podNamespace}
+ if err := pm.Client.Get(ctx, nsn, &corev1.Secret{}); apierrors.IsNotFound(err) {
+ errs = append(errs, fmt.Errorf("secret %s with certificates does not exists: %w", nsn.String(), err))
+ }
+ }
+ if inst.Spec.Exporter.TLS.ConfigMapName != "" {
+ nsn := types.NamespacedName{Name: inst.Spec.Exporter.TLS.ConfigMapName, Namespace: podNamespace}
+ if err := pm.Client.Get(ctx, nsn, &corev1.ConfigMap{}); apierrors.IsNotFound(err) {
+ errs = append(errs, fmt.Errorf("configmap %s with CA certificate does not exists: %w", nsn.String(), err))
+ }
+ }
+ }
+ if len(errs) > 0 {
+ return errors.Join(errs...)
+ }
+ return nil
+}
diff --git a/pkg/instrumentation/podmutator_test.go b/pkg/instrumentation/podmutator_test.go
index 2eddd045f3..400d44c22b 100644
--- a/pkg/instrumentation/podmutator_test.go
+++ b/pkg/instrumentation/podmutator_test.go
@@ -42,6 +42,8 @@ func TestMutatePod(t *testing.T) {
expected corev1.Pod
inst v1alpha1.Instrumentation
ns corev1.Namespace
+ secret *corev1.Secret
+ configMap *corev1.ConfigMap
setFeatureGates func(t *testing.T)
config config.Config
}{
@@ -52,6 +54,18 @@ func TestMutatePod(t *testing.T) {
Name: "javaagent",
},
},
+ secret: &corev1.Secret{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "my-certs",
+ Namespace: "javaagent",
+ },
+ },
+ configMap: &corev1.ConfigMap{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "my-ca-bundle",
+ Namespace: "javaagent",
+ },
+ },
inst: v1alpha1.Instrumentation{
ObjectMeta: metav1.ObjectMeta{
Name: "example-inst",
@@ -103,6 +117,13 @@ func TestMutatePod(t *testing.T) {
},
Exporter: v1alpha1.Exporter{
Endpoint: "http://collector:12345",
+ TLS: &v1alpha1.TLS{
+ SecretName: "my-certs",
+ ConfigMapName: "my-ca-bundle",
+ CA: "ca.crt",
+ Cert: "cert.crt",
+ Key: "key.key",
+ },
},
},
},
@@ -136,6 +157,24 @@ func TestMutatePod(t *testing.T) {
},
},
},
+ {
+ Name: "otel-auto-secret-my-certs",
+ VolumeSource: corev1.VolumeSource{
+ Secret: &corev1.SecretVolumeSource{
+ SecretName: "my-certs",
+ },
+ },
+ },
+ {
+ Name: "otel-auto-configmap-my-ca-bundle",
+ VolumeSource: corev1.VolumeSource{
+ ConfigMap: &corev1.ConfigMapVolumeSource{
+ LocalObjectReference: corev1.LocalObjectReference{
+ Name: "my-ca-bundle",
+ },
+ },
+ },
+ },
},
InitContainers: []corev1.Container{
{
@@ -212,6 +251,18 @@ func TestMutatePod(t *testing.T) {
Name: "OTEL_SERVICE_NAME",
Value: "app",
},
+ {
+ Name: "OTEL_EXPORTER_OTLP_CERTIFICATE",
+ Value: "/otel-auto-instrumentation-configmap-my-ca-bundle/ca.crt",
+ },
+ {
+ Name: "OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE",
+ Value: "/otel-auto-instrumentation-secret-my-certs/cert.crt",
+ },
+ {
+ Name: "OTEL_EXPORTER_OTLP_CLIENT_KEY",
+ Value: "/otel-auto-instrumentation-secret-my-certs/key.key",
+ },
{
Name: "OTEL_RESOURCE_ATTRIBUTES_POD_NAME",
ValueFrom: &corev1.EnvVarSource{
@@ -238,6 +289,16 @@ func TestMutatePod(t *testing.T) {
Name: javaVolumeName,
MountPath: javaInstrMountPath,
},
+ {
+ Name: "otel-auto-secret-my-certs",
+ ReadOnly: true,
+ MountPath: "/otel-auto-instrumentation-secret-my-certs",
+ },
+ {
+ Name: "otel-auto-configmap-my-ca-bundle",
+ ReadOnly: true,
+ MountPath: "/otel-auto-instrumentation-configmap-my-ca-bundle",
+ },
},
},
},
@@ -4785,6 +4846,49 @@ func TestMutatePod(t *testing.T) {
config.WithEnableNodeJSInstrumentation(false),
),
},
+ {
+ name: "secret and configmap does not exists",
+ ns: corev1.Namespace{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "error-missing-secrets",
+ },
+ },
+ inst: v1alpha1.Instrumentation{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "example-inst",
+ Namespace: "error-missing-secrets",
+ },
+ Spec: v1alpha1.InstrumentationSpec{
+ Exporter: v1alpha1.Exporter{
+ Endpoint: "http://collector:12345",
+ TLS: &v1alpha1.TLS{
+ SecretName: "my-certs",
+ ConfigMapName: "my-ca-bundle",
+ CA: "ca.crt",
+ Cert: "cert.crt",
+ Key: "key.key",
+ },
+ },
+ },
+ },
+ pod: corev1.Pod{
+ ObjectMeta: metav1.ObjectMeta{
+ Annotations: map[string]string{
+ annotationInjectJava: "true",
+ },
+ Namespace: "error-missing-secrets",
+ },
+ Spec: corev1.PodSpec{
+ Containers: []corev1.Container{
+ {
+ Name: "app",
+ },
+ },
+ },
+ },
+ config: config.New(),
+ err: "secret error-missing-secrets/my-certs with certificates does not exists: secrets \"my-certs\" not found\nconfigmap error-missing-secrets/my-ca-bundle with CA certificate does not exists: configmaps \"my-ca-bundle\" not found",
+ },
}
for _, test := range tests {
@@ -4801,6 +4905,21 @@ func TestMutatePod(t *testing.T) {
defer func() {
_ = k8sClient.Delete(context.Background(), &test.ns)
}()
+ if test.secret != nil {
+ err = k8sClient.Create(context.Background(), test.secret)
+ require.NoError(t, err)
+ defer func() {
+ _ = k8sClient.Delete(context.Background(), test.secret)
+ }()
+ }
+ if test.configMap != nil {
+ err = k8sClient.Create(context.Background(), test.configMap)
+ require.NoError(t, err)
+ defer func() {
+ _ = k8sClient.Delete(context.Background(), test.configMap)
+ }()
+ }
+
err = k8sClient.Create(context.Background(), &test.inst)
require.NoError(t, err)
diff --git a/pkg/instrumentation/sdk.go b/pkg/instrumentation/sdk.go
index a9f7d9bbfd..0033f70566 100644
--- a/pkg/instrumentation/sdk.go
+++ b/pkg/instrumentation/sdk.go
@@ -304,15 +304,7 @@ func (i *sdkInjector) injectCommonSDKConfig(ctx context.Context, otelinst v1alph
Value: chooseServiceName(pod, useLabelsForResourceAttributes, resourceMap, appIndex),
})
}
- if otelinst.Spec.Exporter.Endpoint != "" {
- idx = getIndexOfEnv(container.Env, constants.EnvOTELExporterOTLPEndpoint)
- if idx == -1 {
- container.Env = append(container.Env, corev1.EnvVar{
- Name: constants.EnvOTELExporterOTLPEndpoint,
- Value: otelinst.Spec.Endpoint,
- })
- }
- }
+ configureExporter(otelinst.Spec.Exporter, &pod, container)
// Always retrieve the pod name from the Downward API. Ensure that the OTEL_RESOURCE_ATTRIBUTES_POD_NAME env exists.
container.Env = append(container.Env, corev1.EnvVar{
diff --git a/pkg/sidecar/pod.go b/pkg/sidecar/pod.go
index d7db13484c..d7a99918df 100644
--- a/pkg/sidecar/pod.go
+++ b/pkg/sidecar/pod.go
@@ -17,6 +17,7 @@ package sidecar
import (
"fmt"
+ "slices"
"github.com/go-logr/logr"
corev1 "k8s.io/api/core/v1"
@@ -25,6 +26,7 @@ import (
"github.com/open-telemetry/opentelemetry-operator/internal/config"
"github.com/open-telemetry/opentelemetry-operator/internal/manifests/collector"
"github.com/open-telemetry/opentelemetry-operator/internal/naming"
+ "github.com/open-telemetry/opentelemetry-operator/pkg/featuregate"
)
const (
@@ -47,7 +49,17 @@ func add(cfg config.Config, logger logr.Logger, otelcol v1beta1.OpenTelemetryCol
container.Env = append(container.Env, attributes...)
}
pod.Spec.InitContainers = append(pod.Spec.InitContainers, otelcol.Spec.InitContainers...)
- pod.Spec.Containers = append(pod.Spec.Containers, container)
+
+ if featuregate.EnableNativeSidecarContainers.IsEnabled() {
+ policy := corev1.ContainerRestartPolicyAlways
+ container.RestartPolicy = &policy
+ // NOTE: Use ReadinessProbe as startup probe.
+ // See https://github.com/open-telemetry/opentelemetry-operator/pull/2801#discussion_r1547571121
+ container.StartupProbe = container.ReadinessProbe
+ pod.Spec.InitContainers = append(pod.Spec.InitContainers, container)
+ } else {
+ pod.Spec.Containers = append(pod.Spec.Containers, container)
+ }
pod.Spec.Volumes = append(pod.Spec.Volumes, otelcol.Spec.Volumes...)
if pod.Labels == nil {
@@ -58,26 +70,34 @@ func add(cfg config.Config, logger logr.Logger, otelcol v1beta1.OpenTelemetryCol
return pod, nil
}
+func isOtelColContainer(c corev1.Container) bool { return c.Name == naming.Container() }
+
// remove the sidecar container from the given pod.
func remove(pod corev1.Pod) corev1.Pod {
if !existsIn(pod) {
return pod
}
- var containers []corev1.Container
- for _, container := range pod.Spec.Containers {
- if container.Name != naming.Container() {
- containers = append(containers, container)
- }
+ pod.Spec.Containers = slices.DeleteFunc(pod.Spec.Containers, isOtelColContainer)
+
+ if featuregate.EnableNativeSidecarContainers.IsEnabled() {
+ // NOTE: we also remove init containers (native sidecars) since k8s 1.28.
+ // This should have no side effects.
+ pod.Spec.InitContainers = slices.DeleteFunc(pod.Spec.InitContainers, isOtelColContainer)
}
- pod.Spec.Containers = containers
return pod
}
// existsIn checks whether a sidecar container exists in the given pod.
func existsIn(pod corev1.Pod) bool {
- for _, container := range pod.Spec.Containers {
- if container.Name == naming.Container() {
+ if slices.ContainsFunc(pod.Spec.Containers, isOtelColContainer) {
+ return true
+ }
+
+ if featuregate.EnableNativeSidecarContainers.IsEnabled() {
+ // NOTE: we also check init containers (native sidecars) since k8s 1.28.
+ // This should have no side effects.
+ if slices.ContainsFunc(pod.Spec.InitContainers, isOtelColContainer) {
return true
}
}
diff --git a/pkg/sidecar/pod_test.go b/pkg/sidecar/pod_test.go
index c941961181..58c0de9841 100644
--- a/pkg/sidecar/pod_test.go
+++ b/pkg/sidecar/pod_test.go
@@ -19,6 +19,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ colfeaturegate "go.opentelemetry.io/collector/featuregate"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
logf "sigs.k8s.io/controller-runtime/pkg/log"
@@ -26,10 +27,99 @@ import (
"github.com/open-telemetry/opentelemetry-operator/apis/v1beta1"
"github.com/open-telemetry/opentelemetry-operator/internal/config"
"github.com/open-telemetry/opentelemetry-operator/internal/naming"
+ "github.com/open-telemetry/opentelemetry-operator/pkg/featuregate"
)
var logger = logf.Log.WithName("unit-tests")
+func enableSidecarFeatureGate(t *testing.T) {
+ originalVal := featuregate.EnableNativeSidecarContainers.IsEnabled()
+ t.Logf("original is: %+v", originalVal)
+ require.NoError(t, colfeaturegate.GlobalRegistry().Set(featuregate.EnableNativeSidecarContainers.ID(), true))
+ t.Cleanup(func() {
+ require.NoError(t, colfeaturegate.GlobalRegistry().Set(featuregate.EnableNativeSidecarContainers.ID(), originalVal))
+ })
+}
+
+func TestAddNativeSidecar(t *testing.T) {
+ enableSidecarFeatureGate(t)
+ // prepare
+ pod := corev1.Pod{
+ Spec: corev1.PodSpec{
+ Containers: []corev1.Container{
+ {Name: "my-app"},
+ },
+ InitContainers: []corev1.Container{
+ {
+ Name: "my-init",
+ },
+ },
+ // cross-test: the pod has a volume already, make sure we don't remove it
+ Volumes: []corev1.Volume{{}},
+ },
+ }
+
+ otelcol := v1beta1.OpenTelemetryCollector{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "otelcol-native-sidecar",
+ Namespace: "some-app",
+ },
+ Spec: v1beta1.OpenTelemetryCollectorSpec{
+ Mode: v1beta1.ModeSidecar,
+ OpenTelemetryCommonFields: v1beta1.OpenTelemetryCommonFields{
+ InitContainers: []corev1.Container{
+ {
+ Name: "test",
+ },
+ },
+ },
+ },
+ }
+
+ otelcolYaml, err := otelcol.Spec.Config.Yaml()
+ require.NoError(t, err)
+ cfg := config.New(config.WithCollectorImage("some-default-image"))
+
+ // test
+ changed, err := add(cfg, logger, otelcol, pod, nil)
+
+ // verify
+ assert.NoError(t, err)
+ require.Len(t, changed.Spec.Containers, 1)
+ require.Len(t, changed.Spec.InitContainers, 3)
+ require.Len(t, changed.Spec.Volumes, 1)
+ assert.Equal(t, "some-app.otelcol-native-sidecar",
+ changed.Labels["sidecar.opentelemetry.io/injected"])
+ expectedPolicy := corev1.ContainerRestartPolicyAlways
+ assert.Equal(t, corev1.Container{
+ Name: "otc-container",
+ Image: "some-default-image",
+ Args: []string{"--config=env:OTEL_CONFIG"},
+ RestartPolicy: &expectedPolicy,
+ Env: []corev1.EnvVar{
+ {
+ Name: "POD_NAME",
+ ValueFrom: &corev1.EnvVarSource{
+ FieldRef: &corev1.ObjectFieldSelector{
+ FieldPath: "metadata.name",
+ },
+ },
+ },
+ {
+ Name: "OTEL_CONFIG",
+ Value: string(otelcolYaml),
+ },
+ },
+ Ports: []corev1.ContainerPort{
+ {
+ Name: "metrics",
+ ContainerPort: 8888,
+ Protocol: corev1.ProtocolTCP,
+ },
+ },
+ }, changed.Spec.InitContainers[2])
+}
+
func TestAddSidecarWhenNoSidecarExists(t *testing.T) {
// prepare
pod := corev1.Pod{
@@ -146,6 +236,11 @@ func TestRemoveSidecar(t *testing.T) {
{Name: naming.Container()},
{Name: naming.Container()}, // two sidecars! should remove both
},
+ InitContainers: []corev1.Container{
+ {Name: "something"},
+ {Name: naming.Container()}, // NOTE: native sidecar since k8s 1.28.
+ {Name: naming.Container()}, // two sidecars! should remove both
+ },
},
}
@@ -174,6 +269,8 @@ func TestRemoveNonExistingSidecar(t *testing.T) {
}
func TestExistsIn(t *testing.T) {
+ enableSidecarFeatureGate(t)
+
for _, tt := range []struct {
desc string
pod corev1.Pod
@@ -190,6 +287,19 @@ func TestExistsIn(t *testing.T) {
},
true},
+ {"does-have-native-sidecar",
+ corev1.Pod{
+ Spec: corev1.PodSpec{
+ Containers: []corev1.Container{
+ {Name: "my-app"},
+ },
+ InitContainers: []corev1.Container{
+ {Name: naming.Container()},
+ },
+ },
+ },
+ true},
+
{"does-not-have-sidecar",
corev1.Pod{
Spec: corev1.PodSpec{
diff --git a/tests/e2e-instrumentation/instrumentation-java-tls/.gitignore b/tests/e2e-instrumentation/instrumentation-java-tls/.gitignore
new file mode 100644
index 0000000000..b8987f0ba0
--- /dev/null
+++ b/tests/e2e-instrumentation/instrumentation-java-tls/.gitignore
@@ -0,0 +1,2 @@
+*.crt
+*.key
\ No newline at end of file
diff --git a/tests/e2e-instrumentation/instrumentation-java-tls/00-install-collector.yaml b/tests/e2e-instrumentation/instrumentation-java-tls/00-install-collector.yaml
new file mode 100644
index 0000000000..536c392481
--- /dev/null
+++ b/tests/e2e-instrumentation/instrumentation-java-tls/00-install-collector.yaml
@@ -0,0 +1,43 @@
+apiVersion: opentelemetry.io/v1beta1
+kind: OpenTelemetryCollector
+metadata:
+ name: simplest
+spec:
+ volumeMounts:
+ - name: certs
+ mountPath: /certs
+ - name: certs-ca
+ mountPath: /certs-ca
+ volumes:
+ - name: certs
+ secret:
+ secretName: server-certs
+ - name: certs-ca
+ configMap:
+ name: ca
+ config:
+ receivers:
+ otlp:
+ protocols:
+ grpc:
+ endpoint: 0.0.0.0:4317
+ tls:
+ cert_file: /certs/tls.crt
+ key_file: /certs/tls.key
+ client_ca_file: /certs-ca/ca.crt
+ http:
+ endpoint: 0.0.0.0:4318
+ tls:
+ cert_file: /certs/tls.crt
+ key_file: /certs/tls.key
+ client_ca_file: /certs-ca/ca.crt
+ processors:
+
+ exporters:
+ debug: {}
+
+ service:
+ pipelines:
+ traces:
+ receivers: [otlp]
+ exporters: [debug]
diff --git a/tests/e2e-instrumentation/instrumentation-java-tls/00-install-instrumentation.yaml b/tests/e2e-instrumentation/instrumentation-java-tls/00-install-instrumentation.yaml
new file mode 100644
index 0000000000..7bc75d7107
--- /dev/null
+++ b/tests/e2e-instrumentation/instrumentation-java-tls/00-install-instrumentation.yaml
@@ -0,0 +1,19 @@
+apiVersion: opentelemetry.io/v1alpha1
+kind: Instrumentation
+metadata:
+ name: java
+spec:
+ exporter:
+ endpoint: https://simplest-collector:4317
+ tls:
+ secretName: client-certs
+ configMapName: ca
+ ca_file: ca.crt
+ cert_file: tls.crt
+ key_file: tls.key
+ propagators:
+ - tracecontext
+ - baggage
+ sampler:
+ type: parentbased_traceidratio
+ argument: "1"
diff --git a/tests/e2e-instrumentation/instrumentation-java-tls/01-assert.yaml b/tests/e2e-instrumentation/instrumentation-java-tls/01-assert.yaml
new file mode 100644
index 0000000000..7ddecadb47
--- /dev/null
+++ b/tests/e2e-instrumentation/instrumentation-java-tls/01-assert.yaml
@@ -0,0 +1,70 @@
+apiVersion: v1
+kind: Pod
+metadata:
+ annotations:
+ instrumentation.opentelemetry.io/inject-java: "true"
+ labels:
+ app: my-java
+spec:
+ containers:
+ - env:
+ - name: OTEL_NODE_IP
+ valueFrom:
+ fieldRef:
+ fieldPath: status.hostIP
+ - name: OTEL_POD_IP
+ valueFrom:
+ fieldRef:
+ fieldPath: status.podIP
+ - name: JAVA_TOOL_OPTIONS
+ value: ' -javaagent:/otel-auto-instrumentation-java/javaagent.jar'
+ - name: OTEL_SERVICE_NAME
+ value: my-java
+ - name: OTEL_EXPORTER_OTLP_ENDPOINT
+ value: https://simplest-collector:4317
+ - name: OTEL_EXPORTER_OTLP_CERTIFICATE
+ value: /otel-auto-instrumentation-configmap-ca/ca.crt
+ - name: OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE
+ value: /otel-auto-instrumentation-secret-client-certs/tls.crt
+ - name: OTEL_EXPORTER_OTLP_CLIENT_KEY
+ value: /otel-auto-instrumentation-secret-client-certs/tls.key
+ - name: OTEL_RESOURCE_ATTRIBUTES_POD_NAME
+ valueFrom:
+ fieldRef:
+ apiVersion: v1
+ fieldPath: metadata.name
+ - name: OTEL_RESOURCE_ATTRIBUTES_NODE_NAME
+ valueFrom:
+ fieldRef:
+ apiVersion: v1
+ fieldPath: spec.nodeName
+ - name: OTEL_PROPAGATORS
+ value: tracecontext,baggage
+ - name: OTEL_TRACES_SAMPLER
+ value: parentbased_traceidratio
+ - name: OTEL_TRACES_SAMPLER_ARG
+ value: "1"
+ - name: OTEL_RESOURCE_ATTRIBUTES
+ name: myapp
+ volumeMounts:
+ - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
+ readOnly: true
+ - mountPath: /otel-auto-instrumentation-java
+ name: opentelemetry-auto-instrumentation-java
+ - mountPath: /otel-auto-instrumentation-secret-client-certs
+ name: otel-auto-secret-client-certs
+ readOnly: true
+ - mountPath: /otel-auto-instrumentation-configmap-ca
+ name: otel-auto-configmap-ca
+ readOnly: true
+ initContainers:
+ - name: opentelemetry-auto-instrumentation-java
+status:
+ containerStatuses:
+ - name: myapp
+ ready: true
+ started: true
+ initContainerStatuses:
+ - name: opentelemetry-auto-instrumentation-java
+ ready: true
+ phase: Running
diff --git a/tests/e2e-instrumentation/instrumentation-java-tls/01-install-app.yaml b/tests/e2e-instrumentation/instrumentation-java-tls/01-install-app.yaml
new file mode 100644
index 0000000000..0d16826e53
--- /dev/null
+++ b/tests/e2e-instrumentation/instrumentation-java-tls/01-install-app.yaml
@@ -0,0 +1,27 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: my-java
+spec:
+ selector:
+ matchLabels:
+ app: my-java
+ replicas: 1
+ template:
+ metadata:
+ labels:
+ app: my-java
+ annotations:
+ instrumentation.opentelemetry.io/inject-java: "true"
+ spec:
+ securityContext:
+ runAsUser: 1000
+ runAsGroup: 3000
+ fsGroup: 3000
+ containers:
+ - name: myapp
+ image: ghcr.io/open-telemetry/opentelemetry-operator/e2e-test-app-java:main
+ securityContext:
+ allowPrivilegeEscalation: false
+ capabilities:
+ drop: ["ALL"]
diff --git a/tests/e2e-instrumentation/instrumentation-java-tls/ca.yaml b/tests/e2e-instrumentation/instrumentation-java-tls/ca.yaml
new file mode 100644
index 0000000000..c078708fd6
--- /dev/null
+++ b/tests/e2e-instrumentation/instrumentation-java-tls/ca.yaml
@@ -0,0 +1,30 @@
+apiVersion: v1
+data:
+ ca.crt: |
+ -----BEGIN CERTIFICATE-----
+ MIID3zCCAsegAwIBAgIUbgTamPDD9mF7SzjykOtjZ6eOJygwDQYJKoZIhvcNAQEL
+ BQAwfjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM
+ DU1vdW50YWluIFZpZXcxGjAYBgNVBAoMEVlvdXIgT3JnYW5pemF0aW9uMRIwEAYD
+ VQQLDAlZb3VyIFVuaXQxEjAQBgNVBAMMCWxvY2FsaG9zdDAgFw0yNDEwMTAxMjQw
+ MTFaGA8yMDUxMDMxMzEyNDAxMVowfjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh
+ bGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxGjAYBgNVBAoMEVlvdXIg
+ T3JnYW5pemF0aW9uMRIwEAYDVQQLDAlZb3VyIFVuaXQxEjAQBgNVBAMMCWxvY2Fs
+ aG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMax8x9QrIB924Tn
+ J+GhOsvEU6DDTbntLS8rXy7ePeCrUgjh+E3ThzvdZFqqx8ffVmrDVd8SF9TabXWC
+ j4Bytyv1AxBN8+PviXjyDeF5qSYEzh9K9poJCnTPOXZcToEna0Q5Po41fFY/M5QL
+ 7YHBrlc4rJKd+CJmQ0bjUj1OjG0NBT2Xm0rU1o92+73CMb//ADd8XkqDunHMfILe
+ wyWDiTbXsgXuh62cdmQyAL98xH0ghSrGYM2KA/F9FvD51B2+CDs2YwET4IsRTAt+
+ 9nLJpjrN7o+lofnhGWy88wPwlzJZeMP3oyna2iVlemXXYZeYXv2uRN6DCLUaamXT
+ sy2sawECAwEAAaNTMFEwHQYDVR0OBBYEFI7foDRaBz788AJJcAo0wC422LDUMB8G
+ A1UdIwQYMBaAFI7foDRaBz788AJJcAo0wC422LDUMA8GA1UdEwEB/wQFMAMBAf8w
+ DQYJKoZIhvcNAQELBQADggEBAIyVPNo2vsiRoqeJjaDCUSJFzop4ykdQOsOUMeJT
+ UqiJvH87unmEm50QgGOwsSxYPZkaPosxjnIFs9lVXixIcETtqbb8DT2AU9muDJ4o
+ 2p8tYBD/4jTN0I6waEpsubMwz+U4llxyfCG0UK3/6kpFwi8/723i8LwzynwkMiki
+ gtAPGmo1QwMFW/2w24l/+Uo4dhrq3GpuV2qBwyYc04z88abvAzRy/wIdw0IC4DiO
+ nNNN1SsjAeN+wp1dm0ohDm4z5d60O9CiTtggizzONJ8tln9SkyN6fCvpArgp9xxD
+ vChKkZiGSJlRoql1k8nRvHBaPZ9e3L8MEw7LgrkPSgleaNI=
+ -----END CERTIFICATE-----
+kind: ConfigMap
+metadata:
+ creationTimestamp: null
+ name: ca
diff --git a/tests/e2e-instrumentation/instrumentation-java-tls/chainsaw-test.yaml b/tests/e2e-instrumentation/instrumentation-java-tls/chainsaw-test.yaml
new file mode 100755
index 0000000000..f552743fa3
--- /dev/null
+++ b/tests/e2e-instrumentation/instrumentation-java-tls/chainsaw-test.yaml
@@ -0,0 +1,46 @@
+# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json
+apiVersion: chainsaw.kyverno.io/v1alpha1
+kind: Test
+metadata:
+ creationTimestamp: null
+ name: instrumentation-java-tls
+spec:
+ steps:
+ - name: step-00
+ try:
+ # In OpenShift, when a namespace is created, all necessary SCC annotations are automatically added. However, if a namespace is created using a resource file with only selected SCCs, the other auto-added SCCs are not included. Therefore, the UID-range and supplemental groups SCC annotations must be set after the namespace is created.
+ - command:
+ entrypoint: kubectl
+ args:
+ - annotate
+ - namespace
+ - ${NAMESPACE}
+ - openshift.io/sa.scc.uid-range=1000/1000
+ - --overwrite
+ - command:
+ entrypoint: kubectl
+ args:
+ - annotate
+ - namespace
+ - ${NAMESPACE}
+ - openshift.io/sa.scc.supplemental-groups=3000/3000
+ - --overwrite
+ - apply:
+ file: ca.yaml
+ - apply:
+ file: client-secret.yaml
+ - apply:
+ file: server-secret.yaml
+ - apply:
+ file: 00-install-collector.yaml
+ - apply:
+ file: 00-install-instrumentation.yaml
+ - name: step-01
+ try:
+ - apply:
+ file: 01-install-app.yaml
+ - assert:
+ file: 01-assert.yaml
+ catch:
+ - podLogs:
+ selector: app=my-java
\ No newline at end of file
diff --git a/tests/e2e-instrumentation/instrumentation-java-tls/client-secret.yaml b/tests/e2e-instrumentation/instrumentation-java-tls/client-secret.yaml
new file mode 100644
index 0000000000..d038b02d89
--- /dev/null
+++ b/tests/e2e-instrumentation/instrumentation-java-tls/client-secret.yaml
@@ -0,0 +1,9 @@
+apiVersion: v1
+data:
+ tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUQ2VENDQXRHZ0F3SUJBZ0lCQVRBTkJna3Foa2lHOXcwQkFRc0ZBREIrTVFzd0NRWURWUVFHRXdKVlV6RVQKTUJFR0ExVUVDQXdLUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnd3TlRXOTFiblJoYVc0Z1ZtbGxkekVhTUJnRwpBMVVFQ2d3UldXOTFjaUJQY21kaGJtbDZZWFJwYjI0eEVqQVFCZ05WQkFzTUNWbHZkWElnVlc1cGRERVNNQkFHCkExVUVBd3dKYkc5allXeG9iM04wTUNBWERUSTBNVEF4TURFeU5EQXhNVm9ZRHpJd05URXdNekV6TVRJME1ERXgKV2pDQm1qRUxNQWtHQTFVRUJoTUNWVk14RXpBUkJnTlZCQWdNQ2tOaGJHbG1iM0p1YVdFeEZqQVVCZ05WQkFjTQpEVTF2ZFc1MFlXbHVJRlpwWlhjeEdqQVlCZ05WQkFvTUVWbHZkWElnVDNKbllXNXBlbUYwYVc5dU1SSXdFQVlEClZRUUxEQWxaYjNWeUlGVnVhWFF4R2pBWUJnTlZCQU1NRVhOMll5NWpiSFZ6ZEdWeUxteHZZMkZzTVJJd0VBWUQKVlFRRERBbHNiMk5oYkdodmMzUXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDeApNSzljZDgvb0tHL0FGaTZUS2tsYmNzdlNSS0dTQUkvU2NSNVJQU3FoVW5sQ1NITEhpdXU0TDhSS202RGhGekVaCngvVVppSlREU3BWTllKcHpzZ1B5YkxWU1NQL2k5SDVqWGc3NW5MbUNUNmtRYWV5NG5EUjBZMEp3ZkdaaDB0eWwKMnpMMUlZdnVCYkZQTjMwRVp0bE82WVN3eWtqYjMwcjl3eFhrS1lsMFlCcEJFbkpqYyt5SW44OW52amNtTHgvVApkd3JPTlNXc2QzdXJpdXJNMWFWQlFjd09tMG8rMG9aVFdJY2daa2hPM0cvV29uZHBnSVl2OWF6dWYrL2craWs1ClQwZXBQR3RJSUsrajNqN3lGb3lkMFVONmprb2hyclV1bUFZRmF5UkdkRjhxNzc5dXIxZ0hIcXozRkE0YVY3aEoKd2JWNTNLV0ZCb2hLZEtqQkdVcHBBZ01CQUFHalV6QlJNQjBHQTFVZERnUVdCQlFhK2NpYTZvaS9RenhtZm43RgpiQnhOWTF0bXpEQWZCZ05WSFNNRUdEQVdnQlNPMzZBMFdnYysvUEFDU1hBS05NQXVOdGl3MURBUEJnTlZIUk1CCkFmOEVCVEFEQVFIL01BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQ0xvYTFIWnd5aGRQMyt4cXZYUzN5Z0FlbDAKMTdXWEpuM0FocndsajRxUFpvR2NrT0FYY1RoYm9ZaExITnV1ZVpPRkpIWFd4dU5lZDR2Y2xONEVocFdrWVRZTApodUtDN1IvVFVXVnAxMnh1SzNsdTBMZ3ZacUQ5bW05bTlXUW02eVJ5dmZCT0JBc3BLYXdtd0ljS0NLa3RCUnRpClRBaWxxNy9zOVZKRnFtSWNWWEg5bGtIaWNBMUROUjhMc2JSUWJtMUZOSCt4eGd1bTd6cURJbGZlZzhFMkg3WVIKVnRpNXZmZmRUUHVqZHlGaWZJbHR0cmw0MThwVDNVWEJ3UWFGRkVJSHlFdjlDamI5RFRMWDMrTDdlaWVYdXNrcgpxUkZzVjFIa3Arc1IwMTVNckxpUU9uOThjYUlKcG4yN3JOaU9GeVU2b3R3eTR0WGtmd0RTNlJLMkV5T24KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
+ tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ3hNSzljZDgvb0tHL0EKRmk2VEtrbGJjc3ZTUktHU0FJL1NjUjVSUFNxaFVubENTSExIaXV1NEw4UkttNkRoRnpFWngvVVppSlREU3BWTgpZSnB6c2dQeWJMVlNTUC9pOUg1alhnNzVuTG1DVDZrUWFleTRuRFIwWTBKd2ZHWmgwdHlsMnpMMUlZdnVCYkZQCk4zMEVadGxPNllTd3lramIzMHI5d3hYa0tZbDBZQnBCRW5KamMreUluODludmpjbUx4L1Rkd3JPTlNXc2QzdXIKaXVyTTFhVkJRY3dPbTBvKzBvWlRXSWNnWmtoTzNHL1dvbmRwZ0lZdjlhenVmKy9nK2lrNVQwZXBQR3RJSUsragozajd5Rm95ZDBVTjZqa29ocnJVdW1BWUZheVJHZEY4cTc3OXVyMWdISHF6M0ZBNGFWN2hKd2JWNTNLV0ZCb2hLCmRLakJHVXBwQWdNQkFBRUNnZ0VBQ2ozZzZQbnc2R3BMN3FEKzcxa3luOGlqeTRNcTNwNzRob2FzejFwM0tCZDEKdEZVdWlKRDQvUzYwOXh0YlFoOXp6UVJ2NEVVSUtqM3U5dEpydUY1cUF0TEhRVVZyRmFjaHEyU0YvanRtNy9JTgpvNG45THVlSDB2d09IS1V5eXNVNWVwUmxYb3kzbUpvTXpMZDRSYTlITU1hU2VhQ0dTUlUxUndrd3hGSjZwRGExCml2am1neXZJRkp5L3RWMGxQSStUWHpnRzdzdkI1Y01CZDFVNjJXN2VkNDBDQWF6bmg1R09FZHZ1YmFaYmZmSWsKZ2huZ0N0ak5EU0p1Rk5ma1ZXdWNnTmErejVFK2dFYjZBdHJBMEhtZEtVR1V2UkRrNUhiVGZJR09ka0hzcnF5UApSSlk0WndFcEFxMWZhY2FxcWVwMXZsVU5vSmNNTVJhc29VOTZGU0lzelFLQmdRRFpCRFBUa0lQeFFNYXF1c3lDCmw5UkpRVy9OZGpuaDl3enRwOUhYWXNTcUEyU3VQQWVPMGdpWWdBOC9MZUpPTFhYelc0dWp2blhLcENveUNiQ3oKc0IvUm9MeTkrWENiODIzdDlKSTJvczZpbFhGbUo4S21OTUlQdExHVG82T1RJNlNseUNJMUFHRzdtdkVhVWY2SQpmanJaL25pY0c0Tlo5TU5rNVg0M2J5UjUzUUtCZ1FEUkJRU3VNWlNyVFFTMGpWbFZQaGxWdHRhV29vbTE5cFRjCmpjYS9vRTZ0Z2RRb2dUalVEZDlDRmtJZ1VxYmNpYlo0ZitnUmhHNHF4VkxwMDBxR0JLWFdYOXlBQTBtMmpNa3MKZkFDbTdZbFNvTElLNkY2M0FuWk9Kck5ETWYyejd1WWthWDBQRk4rTXZsLzRiQTFYMTFEcFRSdG4vL2QyLzBuMwpTeW1LWnVJWC9RS0JnRkh5TjB1OU4wVmpLMkdPdGVqZVFpZ0RVSjlwOUVOeVVXeHdRVm11andxUHkzWExieU1zCkJsam5pbHBXRGkxdEZ5djB0bzczUFcxdWZneDFBa2RueXl3U0lSTXZYS2xXeTN6ZUxGUDdPRUhHWXBLcmt1SEYKN0QyWUFySDRTYTBtK1dZc1kxWldOWkZzMlh3UjJDWmNYQWF6QTRJWEZZdGpWR0VHRTVvRkd1WDFBb0dBTTVXWAplQjRJWU5aYktPd1JkZllqYm9IM0o2bnBicHp5VkJReFRxMlRmVUtqUjNQTXdKakQxcDJEcUZKOWw4UHM0b1ErCms4UXBKQ2thczFaUCtBOUJsa3lHTUptZklZeFJRY2RBcWZISmlEamNkOUN0UDJFK0xUOWowbHVPRDFBUVFFQkEKZXU1ZDFYQk9ZeExYb0N3bGJjNTN5d3ppMTkxZE5jaTQ4YzArVTBrQ2dZRUF5eXdIYkcxOUd4dlNxZXNON2JCQgp6Yy8zYm1qczJocjMvYUxoQWUzMDZUbEdRUkg3Y3lCYzFpR2ZONTF0UTVqV01ZRHg1UndBMmNhUEwwcnl6REhmCjg0SktJeW1pVDB2ckFYRFN2bEorK21BVG1BQnNLcGpSVnpKWTJlVHFqNGQ1NUgyOUdudTVPVUtpMDY1Y2c5WEUKbVIrQ1o5Y1FqN212MDNVbW45MjVJWjQ9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+kind: Secret
+metadata:
+ creationTimestamp: null
+ name: client-certs
+type: kubernetes.io/tls
diff --git a/tests/e2e-instrumentation/instrumentation-java-tls/generate-certs.sh b/tests/e2e-instrumentation/instrumentation-java-tls/generate-certs.sh
new file mode 100755
index 0000000000..d4070b03c9
--- /dev/null
+++ b/tests/e2e-instrumentation/instrumentation-java-tls/generate-certs.sh
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+
+set -ex
+
+# CA key and cert
+openssl req -new -nodes -x509 -days 9650 -keyout ca.key -out ca.crt -subj "/C=US/ST=California/L=Mountain View/O=Your Organization/OU=Your Unit/CN=localhost"
+# Server, E.g. use NDS:*.default.svc.cluster.local for arbitrary collector name deployed in the default namespace
+openssl req -new -nodes -x509 -CA ca.crt -CAkey ca.key -days 9650 -set_serial 01 -keyout server.key -out server.crt -subj "/C=US/ST=California/L=Mountain View/O=Your Organization/OU=Your Unit/CN=svc.cluster.local/CN=localhost" -addext "subjectAltName = DNS:simplest-collector,DNS:localhost"
+# Client
+openssl req -new -nodes -x509 -CA ca.crt -CAkey ca.key -days 9650 -set_serial 01 -keyout client.key -out client.crt -subj "/C=US/ST=California/L=Mountain View/O=Your Organization/OU=Your Unit/CN=svc.cluster.local/CN=localhost"
+
+kubectl create configmap ca --from-file=ca.crt=ca.crt -o yaml --dry-run=client > ca.yaml
+kubectl create secret tls server-certs --cert=server.crt --key=server.key -o yaml --dry-run=client > server-secret.yaml
+kubectl create secret tls client-certs --cert=client.crt --key=client.key -o yaml --dry-run=client > client-secret.yaml
diff --git a/tests/e2e-instrumentation/instrumentation-java-tls/server-secret.yaml b/tests/e2e-instrumentation/instrumentation-java-tls/server-secret.yaml
new file mode 100644
index 0000000000..63afbd2286
--- /dev/null
+++ b/tests/e2e-instrumentation/instrumentation-java-tls/server-secret.yaml
@@ -0,0 +1,9 @@
+apiVersion: v1
+data:
+ tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVPVENDQXlHZ0F3SUJBZ0lCQVRBTkJna3Foa2lHOXcwQkFRc0ZBREIrTVFzd0NRWURWUVFHRXdKVlV6RVQKTUJFR0ExVUVDQXdLUTJGc2FXWnZjbTVwWVRFV01CUUdBMVVFQnd3TlRXOTFiblJoYVc0Z1ZtbGxkekVhTUJnRwpBMVVFQ2d3UldXOTFjaUJQY21kaGJtbDZZWFJwYjI0eEVqQVFCZ05WQkFzTUNWbHZkWElnVlc1cGRERVNNQkFHCkExVUVBd3dKYkc5allXeG9iM04wTUNBWERUSTBNVEF4TURFeU5EQXhNVm9ZRHpJd05URXdNekV6TVRJME1ERXgKV2pDQm1qRUxNQWtHQTFVRUJoTUNWVk14RXpBUkJnTlZCQWdNQ2tOaGJHbG1iM0p1YVdFeEZqQVVCZ05WQkFjTQpEVTF2ZFc1MFlXbHVJRlpwWlhjeEdqQVlCZ05WQkFvTUVWbHZkWElnVDNKbllXNXBlbUYwYVc5dU1SSXdFQVlEClZRUUxEQWxaYjNWeUlGVnVhWFF4R2pBWUJnTlZCQU1NRVhOMll5NWpiSFZ6ZEdWeUxteHZZMkZzTVJJd0VBWUQKVlFRRERBbHNiMk5oYkdodmMzUXdnZ0VpTUEwR0NTcUdTSWIzRFFFQkFRVUFBNElCRHdBd2dnRUtBb0lCQVFDcgpGN0U5SmtScldZYmM1Wkh2VU5GM2NZNVFaL0FrWktiN1Exend3aGFhQmtqVldWUEJCeUFmakNzM3laU3RGN2RkClo1VUxKNzN1VmtSdEJuTFd5bUJqbTZMN2xHVms2c0VqSXdFQkFUUDVJSksxdjBONFliSExYM1RJMDZXdlNCM2gKbGpjRzZOY0d0djE3NGFnbU1xZ05Bc0lmYlhEcW0xWkZSQzhCa0IwK2Jhc1hLUzJJS3VuSlIweEl1eTlFL09IWgp4b3hLUFFyQjNMcFBJNDAzSThPR2h1alZiY2xvVzh3UEljaVFwOGdJNVU3UWRJWmwzVkszcTZFWkNTVVhiMGNMClEyNnQ3TDZiRmlWcmhrTm5DZGtOU1Fybm55V2p4cldTdmdLTVZWaUtOVU1XQ0pGRWk1MytlSllxZkkzRTBhYXAKNlNsQ3NUQlE2akJYd0Y5R01mRURBZ01CQUFHamdhSXdnWjh3SFFZRFZSME9CQllFRkhZMjV2bmRHZGdDSC9zUgpMREx3Wmc4Ry9reXpNQjhHQTFVZEl3UVlNQmFBRkk3Zm9EUmFCejc4OEFKSmNBbzB3QzQyMkxEVU1BOEdBMVVkCkV3RUIvd1FGTUFNQkFmOHdUQVlEVlIwUkJFVXdRNElTYzJsdGNHeGxjM1F0WTI5c2JHVmpkRzl5Z2lJcUxuUnkKWVdOcGJtY3RjM2x6ZEdWdExuTjJZeTVqYkhWemRHVnlMbXh2WTJGc2dnbHNiMk5oYkdodmMzUXdEUVlKS29aSQpodmNOQVFFTEJRQURnZ0VCQURVNWtCUnRHaTlYalh5TUZJWEdKYTZtNEJrSTFOK0ZqUUprbGVSbWFOaWljRzhwCngzcnNBLzVVZU8wR0pDOXIrMWpxYThtVjhtUzcrMVVNUWJwMTZFUlZOVDBHWnA1TXNFdERqUHBveWFtM1JOZ1YKT2QwMnhZUUNNK3NGMVdNWll3M05FMEszTkJRcncyY3hoKzg2U29GdDBMdDEyYlBmbkxGTzJSdmI3b09aaHB0aApLNjJxaUlOVXAveG85S3hEelVhT1R1SndsTFdmTWQzMS80NFNyZm1hVWpGMWhKRDJ2SHZGeHZhcVNvSmJNK3pkCm1lbGo4cFhkS1ZJaWFRQ3hQZ1E4bTRHUmhQWkFuTk1pVlhiVm9vR05pelFaeEt2UWVwWnpXRTRXNmNFZTJtTWoKYlYvNVBOc3l5Mk0wOWY0MjlvTGxtNEpjb3IyMWZFSGVNVG1PYytzPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
+ tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ3JGN0U5SmtScldZYmMKNVpIdlVORjNjWTVRWi9Ba1pLYjdRMXp3d2hhYUJralZXVlBCQnlBZmpDczN5WlN0RjdkZFo1VUxKNzN1VmtSdApCbkxXeW1Cam02TDdsR1ZrNnNFakl3RUJBVFA1SUpLMXYwTjRZYkhMWDNUSTA2V3ZTQjNobGpjRzZOY0d0djE3CjRhZ21NcWdOQXNJZmJYRHFtMVpGUkM4QmtCMCtiYXNYS1MySUt1bkpSMHhJdXk5RS9PSFp4b3hLUFFyQjNMcFAKSTQwM0k4T0dodWpWYmNsb1c4d1BJY2lRcDhnSTVVN1FkSVpsM1ZLM3E2RVpDU1VYYjBjTFEyNnQ3TDZiRmlWcgpoa05uQ2RrTlNRcm5ueVdqeHJXU3ZnS01WVmlLTlVNV0NKRkVpNTMrZUpZcWZJM0UwYWFwNlNsQ3NUQlE2akJYCndGOUdNZkVEQWdNQkFBRUNnZ0VBQWZ0d3lhQk10SVFoZzVYQzIrZUxvVVhvc1QxejYvVlo1d1BodVNsMW1laXIKU1QwTUZxT1Z4YjdvQ21MUFVsSFdNQkRtTlB5WjFGVUJhMkticjNEUUJCSVV0QWxhWDVqaU9TdDlYeGxVb3NNegp5cGg2MkZxeXUrZTd0Z2UwWGZ0elRMc05hRVBPNEp4dFdOVWgxcVJYdG1yZ1grQzU0aDdWSjFGSkU2L1dJblJJClF1ajEydytCTXVoUUcyRVM0cHpQQ2RtUGgvTkdSV1Q1K0NuamJzMkdjS1EvNXZIaXNnZVAyWEU2ZWRmbldCcFAKN0xNYjFCUGdLU09FTXZ2eUI2R2lMU2xwYWpKTmRtUHpmQmZURllWT05RTk5RYWJhRVFoNG9Gd2s1SkJKTlB5dQo1bCt2UlRpTEtZdk45YzB6Q1ZLa2NuZ0VyaXc0cTVCT3pPa3l1bGlNQVFLQmdRRHNzNkw2UVppNTRTOUh2ckRLCmxSMms4WlRoR1NSZ25uQ1Q2ZHVBcG50VEJpMWs3RUdGWFlWWGtIcEtpZEV5NFNKUmc4bXlSeTNjd1J3S2UzNVgKQVU5aURrajNjN3JLa041RmNleURqTzhXRVptdzZsb213aUtaczk0Y3FHY2tEWnEzSFNROStiMmNjZXFvc3QzSApOWE9ZUHBZdUZKUDAraFFEVFErSytXZUZBd0tCZ1FDNUNxNmJrSEFmQlp3OG5LeG5od3drV21JOTFjV3Fya21VCm5vamRPUkRxV1I1aWZDS05uQi9La0R4RHhGMDNRTjF5alpqcGZFOXdZRm42Vys4ZitPZXNBSGhaODRyZmhUTUgKTTd0VXZoNnNzcSt4QjhkWkJIeTRMd0prQTBPSFBqV2ZtaU96WllwczloUW5WRzAyRDBkdWZlWUNOd0hYN2hTRgptckp6RnJJa0FRS0JnUUNsclZiMk05UGl4MnVBbkVqQ2czMHNacXYrb3NxRGxtTFdKV291c2xpLzFDTVI4UXdyCmZUcElBQ2lZNDc0NkRyc21zMGdLTVNnNHpESUVaRXdhT2lDR1VkbGcydkJ6dU5MYmFOSlRnZUlYWUZwaktxWFAKV3pNOHdsbEZWZHBic2VvSklheXNkSkh6WHdrUTY2R3dQZ21iRnJPbnJWK2lxU2c0NTBkcHp3aFdZUUtCZ0JKNQpWWXRrZFQwem96Q045OHh5T0MwYzlQZjFjc0dpbXVnQ2wrbDJQQkVaaXFZTWZLcWtycXZia0ppM2J4TUlIOVBDCi9VUTZTL2dOTm81L1JUVnM5VHcvNDhRZlEzc2pZai9TMDE0WGlScDIwSUdkSkRMbjlzZXdzYzFvWWdLTG5IRHQKdzZpeWQ0cC9XdTIrU1JUL200TVZnTFF4NTdZMko4aGE5SHYzQlJ3QkFvR0FVMkNXRkJUWk1HL0NCZDhiOG5VeQpHblltNnhIMHpkeWdzK3JWakl5aEhBRXBTODZCaTZGSGh6TkNYRDFjSCtJWjAvYzR0QmYwSjhsVVRvOXpCV1YrClBJNjJOaEVMOW45WjMydTJGNzRDS0VTUi9EdUhTNXBTT2M3eXgvU3BOMjBpUkpodFl5aHA2YU9HMXQwL2NzRHAKVFpvOHlEdzl5cmVTdU9VSUFmM3JraG89Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
+kind: Secret
+metadata:
+ creationTimestamp: null
+ name: server-certs
+type: kubernetes.io/tls
diff --git a/tests/e2e-native-sidecar/00-assert.yaml b/tests/e2e-native-sidecar/00-assert.yaml
new file mode 100644
index 0000000000..823eaf2ad1
--- /dev/null
+++ b/tests/e2e-native-sidecar/00-assert.yaml
@@ -0,0 +1,22 @@
+---
+apiVersion: v1
+kind: Pod
+metadata:
+ annotations:
+ sidecar.opentelemetry.io/inject: "true"
+ name: myapp
+spec:
+ containers:
+ - name: myapp
+ initContainers:
+ - name: otc-container
+ restartPolicy: Always
+status:
+ containerStatuses:
+ - name: myapp
+ ready: true
+ started: true
+ initContainerStatuses:
+ - name: otc-container
+ ready: true
+ started: true
diff --git a/tests/e2e-native-sidecar/00-install.yaml b/tests/e2e-native-sidecar/00-install.yaml
new file mode 100644
index 0000000000..82c54ffdf8
--- /dev/null
+++ b/tests/e2e-native-sidecar/00-install.yaml
@@ -0,0 +1,41 @@
+---
+apiVersion: opentelemetry.io/v1beta1
+kind: OpenTelemetryCollector
+metadata:
+ name: a-sidecar
+spec:
+ mode: sidecar
+ resources:
+ limits:
+ cpu: 500m
+ memory: 128Mi
+ requests:
+ cpu: 5m
+ memory: 64Mi
+
+ config:
+ receivers:
+ otlp:
+ protocols:
+ http: {}
+ exporters:
+ debug: {}
+ service:
+ pipelines:
+ metrics:
+ receivers: [otlp]
+ exporters: [debug]
+---
+apiVersion: v1
+kind: Pod
+metadata:
+ name: myapp
+ annotations:
+ sidecar.opentelemetry.io/inject: "true"
+spec:
+ containers:
+ - name: myapp
+ image: ghcr.io/open-telemetry/opentelemetry-operator/e2e-test-app-python:main
+ ports:
+ - containerPort: 8080
+ protocol: TCP
diff --git a/tests/e2e-native-sidecar/chainsaw-test.yaml b/tests/e2e-native-sidecar/chainsaw-test.yaml
new file mode 100755
index 0000000000..0d93db6d15
--- /dev/null
+++ b/tests/e2e-native-sidecar/chainsaw-test.yaml
@@ -0,0 +1,14 @@
+# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json
+apiVersion: chainsaw.kyverno.io/v1alpha1
+kind: Test
+metadata:
+ creationTimestamp: null
+ name: native-sidecar
+spec:
+ steps:
+ - name: step-00
+ try:
+ - apply:
+ file: 00-install.yaml
+ - assert:
+ file: 00-assert.yaml
diff --git a/tests/e2e-openshift/export-to-cluster-logging-lokistack/chainsaw-test.yaml b/tests/e2e-openshift/export-to-cluster-logging-lokistack/chainsaw-test.yaml
index 15b018f8e2..2678477a1f 100644
--- a/tests/e2e-openshift/export-to-cluster-logging-lokistack/chainsaw-test.yaml
+++ b/tests/e2e-openshift/export-to-cluster-logging-lokistack/chainsaw-test.yaml
@@ -20,6 +20,16 @@ spec:
file: install-minio-assert.yaml
- name: Create the LokiStack instance
try:
+ - command:
+ entrypoint: oc
+ args:
+ - get
+ - storageclass
+ - -o
+ - jsonpath={.items[0].metadata.name}
+ outputs:
+ - name: STORAGE_CLASS_NAME
+ value: ($stdout)
- apply:
file: install-loki.yaml
- assert:
diff --git a/tests/e2e-openshift/export-to-cluster-logging-lokistack/install-loki.yaml b/tests/e2e-openshift/export-to-cluster-logging-lokistack/install-loki.yaml
index 30c5b560e3..e63aa73982 100644
--- a/tests/e2e-openshift/export-to-cluster-logging-lokistack/install-loki.yaml
+++ b/tests/e2e-openshift/export-to-cluster-logging-lokistack/install-loki.yaml
@@ -12,6 +12,6 @@ spec:
secret:
name: logging-loki-s3
type: s3
- storageClassName: gp2-csi
+ storageClassName: ($STORAGE_CLASS_NAME)
tenants:
mode: openshift-logging