diff --git a/.chloggen/instrumentation-support-select.yaml b/.chloggen/instrumentation-support-select.yaml new file mode 100755 index 0000000000..d7f01ed563 --- /dev/null +++ b/.chloggen/instrumentation-support-select.yaml @@ -0,0 +1,16 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action) +component: auto-instrumentation + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Support label selectors in the Instrumentation CR + +# One or more tracking issues related to the change +issues: [2744] + +# (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: diff --git a/apis/v1alpha1/instrumentation_types.go b/apis/v1alpha1/instrumentation_types.go index 8345d3c38a..2aba3a8cab 100644 --- a/apis/v1alpha1/instrumentation_types.go +++ b/apis/v1alpha1/instrumentation_types.go @@ -22,6 +22,13 @@ import ( // InstrumentationSpec defines the desired state of OpenTelemetry SDK and instrumentation. type InstrumentationSpec struct { + // Selector is the label selector for affected Pods. + // This selector only takes effect when annotation: instrumentation.opentelemetry.io/inject-xx equal true. + // Unlike standard label selectors, `nil` means `everything`, and this is also the default. + // This may change in a future CRD version. + // +optional + Selector *metav1.LabelSelector `json:"selector,omitempty"` + // Exporter defines exporter configuration. // +optional Exporter `json:"exporter,omitempty"` diff --git a/apis/v1alpha1/zz_generated.deepcopy.go b/apis/v1alpha1/zz_generated.deepcopy.go index 8f47cb64dc..91b895cc01 100644 --- a/apis/v1alpha1/zz_generated.deepcopy.go +++ b/apis/v1alpha1/zz_generated.deepcopy.go @@ -20,9 +20,9 @@ package v1alpha1 import ( "k8s.io/api/autoscaling/v2" - "k8s.io/api/core/v1" + corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" ) @@ -37,14 +37,14 @@ func (in *ApacheHttpd) DeepCopyInto(out *ApacheHttpd) { } if in.Env != nil { in, out := &in.Env, &out.Env - *out = make([]v1.EnvVar, len(*in)) + *out = make([]corev1.EnvVar, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Attrs != nil { in, out := &in.Attrs, &out.Attrs - *out = make([]v1.EnvVar, len(*in)) + *out = make([]corev1.EnvVar, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -134,7 +134,7 @@ func (in *DotNet) DeepCopyInto(out *DotNet) { } if in.Env != nil { in, out := &in.Env, &out.Env - *out = make([]v1.EnvVar, len(*in)) + *out = make([]corev1.EnvVar, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -192,7 +192,7 @@ func (in *Go) DeepCopyInto(out *Go) { } if in.Env != nil { in, out := &in.Env, &out.Env - *out = make([]v1.EnvVar, len(*in)) + *out = make([]corev1.EnvVar, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -307,6 +307,11 @@ 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 + if in.Selector != nil { + in, out := &in.Selector, &out.Selector + *out = new(v1.LabelSelector) + (*in).DeepCopyInto(*out) + } out.Exporter = in.Exporter in.Resource.DeepCopyInto(&out.Resource) if in.Propagators != nil { @@ -317,7 +322,7 @@ func (in *InstrumentationSpec) DeepCopyInto(out *InstrumentationSpec) { out.Sampler = in.Sampler if in.Env != nil { in, out := &in.Env, &out.Env - *out = make([]v1.EnvVar, len(*in)) + *out = make([]corev1.EnvVar, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -366,7 +371,7 @@ func (in *Java) DeepCopyInto(out *Java) { } if in.Env != nil { in, out := &in.Env, &out.Env - *out = make([]v1.EnvVar, len(*in)) + *out = make([]corev1.EnvVar, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -434,14 +439,14 @@ func (in *Nginx) DeepCopyInto(out *Nginx) { } if in.Env != nil { in, out := &in.Env, &out.Env - *out = make([]v1.EnvVar, len(*in)) + *out = make([]corev1.EnvVar, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Attrs != nil { in, out := &in.Attrs, &out.Attrs - *out = make([]v1.EnvVar, len(*in)) + *out = make([]corev1.EnvVar, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -469,7 +474,7 @@ func (in *NodeJS) DeepCopyInto(out *NodeJS) { } if in.Env != nil { in, out := &in.Env, &out.Env - *out = make([]v1.EnvVar, len(*in)) + *out = make([]corev1.EnvVar, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -610,12 +615,12 @@ func (in *OpAMPBridgeSpec) DeepCopyInto(out *OpAMPBridgeSpec) { } if in.SecurityContext != nil { in, out := &in.SecurityContext, &out.SecurityContext - *out = new(v1.SecurityContext) + *out = new(corev1.SecurityContext) (*in).DeepCopyInto(*out) } if in.PodSecurityContext != nil { in, out := &in.PodSecurityContext, &out.PodSecurityContext - *out = new(v1.PodSecurityContext) + *out = new(corev1.PodSecurityContext) (*in).DeepCopyInto(*out) } if in.PodAnnotations != nil { @@ -627,54 +632,54 @@ func (in *OpAMPBridgeSpec) DeepCopyInto(out *OpAMPBridgeSpec) { } if in.VolumeMounts != nil { in, out := &in.VolumeMounts, &out.VolumeMounts - *out = make([]v1.VolumeMount, len(*in)) + *out = make([]corev1.VolumeMount, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Ports != nil { in, out := &in.Ports, &out.Ports - *out = make([]v1.ServicePort, len(*in)) + *out = make([]corev1.ServicePort, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Env != nil { in, out := &in.Env, &out.Env - *out = make([]v1.EnvVar, len(*in)) + *out = make([]corev1.EnvVar, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.EnvFrom != nil { in, out := &in.EnvFrom, &out.EnvFrom - *out = make([]v1.EnvFromSource, len(*in)) + *out = make([]corev1.EnvFromSource, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Tolerations != nil { in, out := &in.Tolerations, &out.Tolerations - *out = make([]v1.Toleration, len(*in)) + *out = make([]corev1.Toleration, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Volumes != nil { in, out := &in.Volumes, &out.Volumes - *out = make([]v1.Volume, len(*in)) + *out = make([]corev1.Volume, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Affinity != nil { in, out := &in.Affinity, &out.Affinity - *out = new(v1.Affinity) + *out = new(corev1.Affinity) (*in).DeepCopyInto(*out) } if in.TopologySpreadConstraints != nil { in, out := &in.TopologySpreadConstraints, &out.TopologySpreadConstraints - *out = make([]v1.TopologySpreadConstraint, len(*in)) + *out = make([]corev1.TopologySpreadConstraint, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -825,12 +830,12 @@ func (in *OpenTelemetryCollectorSpec) DeepCopyInto(out *OpenTelemetryCollectorSp } if in.SecurityContext != nil { in, out := &in.SecurityContext, &out.SecurityContext - *out = new(v1.SecurityContext) + *out = new(corev1.SecurityContext) (*in).DeepCopyInto(*out) } if in.PodSecurityContext != nil { in, out := &in.PodSecurityContext, &out.PodSecurityContext - *out = new(v1.PodSecurityContext) + *out = new(corev1.PodSecurityContext) (*in).DeepCopyInto(*out) } if in.PodAnnotations != nil { @@ -843,7 +848,7 @@ func (in *OpenTelemetryCollectorSpec) DeepCopyInto(out *OpenTelemetryCollectorSp in.TargetAllocator.DeepCopyInto(&out.TargetAllocator) if in.VolumeMounts != nil { in, out := &in.VolumeMounts, &out.VolumeMounts - *out = make([]v1.VolumeMount, len(*in)) + *out = make([]corev1.VolumeMount, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -857,35 +862,35 @@ func (in *OpenTelemetryCollectorSpec) DeepCopyInto(out *OpenTelemetryCollectorSp } if in.Env != nil { in, out := &in.Env, &out.Env - *out = make([]v1.EnvVar, len(*in)) + *out = make([]corev1.EnvVar, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.EnvFrom != nil { in, out := &in.EnvFrom, &out.EnvFrom - *out = make([]v1.EnvFromSource, len(*in)) + *out = make([]corev1.EnvFromSource, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.VolumeClaimTemplates != nil { in, out := &in.VolumeClaimTemplates, &out.VolumeClaimTemplates - *out = make([]v1.PersistentVolumeClaim, len(*in)) + *out = make([]corev1.PersistentVolumeClaim, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Tolerations != nil { in, out := &in.Tolerations, &out.Tolerations - *out = make([]v1.Toleration, len(*in)) + *out = make([]corev1.Toleration, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Volumes != nil { in, out := &in.Volumes, &out.Volumes - *out = make([]v1.Volume, len(*in)) + *out = make([]corev1.Volume, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -893,12 +898,12 @@ func (in *OpenTelemetryCollectorSpec) DeepCopyInto(out *OpenTelemetryCollectorSp in.Ingress.DeepCopyInto(&out.Ingress) if in.Affinity != nil { in, out := &in.Affinity, &out.Affinity - *out = new(v1.Affinity) + *out = new(corev1.Affinity) (*in).DeepCopyInto(*out) } if in.Lifecycle != nil { in, out := &in.Lifecycle, &out.Lifecycle - *out = new(v1.Lifecycle) + *out = new(corev1.Lifecycle) (*in).DeepCopyInto(*out) } if in.TerminationGracePeriodSeconds != nil { @@ -913,14 +918,14 @@ func (in *OpenTelemetryCollectorSpec) DeepCopyInto(out *OpenTelemetryCollectorSp } if in.InitContainers != nil { in, out := &in.InitContainers, &out.InitContainers - *out = make([]v1.Container, len(*in)) + *out = make([]corev1.Container, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.AdditionalContainers != nil { in, out := &in.AdditionalContainers, &out.AdditionalContainers - *out = make([]v1.Container, len(*in)) + *out = make([]corev1.Container, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -928,7 +933,7 @@ func (in *OpenTelemetryCollectorSpec) DeepCopyInto(out *OpenTelemetryCollectorSp out.Observability = in.Observability if in.TopologySpreadConstraints != nil { in, out := &in.TopologySpreadConstraints, &out.TopologySpreadConstraints - *out = make([]v1.TopologySpreadConstraint, len(*in)) + *out = make([]corev1.TopologySpreadConstraint, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -991,37 +996,37 @@ func (in *OpenTelemetryTargetAllocator) DeepCopyInto(out *OpenTelemetryTargetAll in.Resources.DeepCopyInto(&out.Resources) if in.Affinity != nil { in, out := &in.Affinity, &out.Affinity - *out = new(v1.Affinity) + *out = new(corev1.Affinity) (*in).DeepCopyInto(*out) } in.PrometheusCR.DeepCopyInto(&out.PrometheusCR) if in.SecurityContext != nil { in, out := &in.SecurityContext, &out.SecurityContext - *out = new(v1.SecurityContext) + *out = new(corev1.SecurityContext) (*in).DeepCopyInto(*out) } if in.PodSecurityContext != nil { in, out := &in.PodSecurityContext, &out.PodSecurityContext - *out = new(v1.PodSecurityContext) + *out = new(corev1.PodSecurityContext) (*in).DeepCopyInto(*out) } if in.TopologySpreadConstraints != nil { in, out := &in.TopologySpreadConstraints, &out.TopologySpreadConstraints - *out = make([]v1.TopologySpreadConstraint, len(*in)) + *out = make([]corev1.TopologySpreadConstraint, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Tolerations != nil { in, out := &in.Tolerations, &out.Tolerations - *out = make([]v1.Toleration, len(*in)) + *out = make([]corev1.Toleration, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } if in.Env != nil { in, out := &in.Env, &out.Env - *out = make([]v1.EnvVar, len(*in)) + *out = make([]corev1.EnvVar, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -1049,7 +1054,7 @@ func (in *OpenTelemetryTargetAllocatorPrometheusCR) DeepCopyInto(out *OpenTeleme *out = *in if in.ScrapeInterval != nil { in, out := &in.ScrapeInterval, &out.ScrapeInterval - *out = new(metav1.Duration) + *out = new(v1.Duration) **out = **in } if in.PodMonitorSelector != nil { @@ -1174,7 +1179,7 @@ func (in *Python) DeepCopyInto(out *Python) { } if in.Env != nil { in, out := &in.Env, &out.Env - *out = make([]v1.EnvVar, len(*in)) + *out = make([]corev1.EnvVar, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } diff --git a/bundle/manifests/opentelemetry.io_instrumentations.yaml b/bundle/manifests/opentelemetry.io_instrumentations.yaml index 4fd5de9a21..4829733363 100644 --- a/bundle/manifests/opentelemetry.io_instrumentations.yaml +++ b/bundle/manifests/opentelemetry.io_instrumentations.yaml @@ -1039,6 +1039,30 @@ spec: - xray type: string type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic type: object status: type: object diff --git a/config/crd/bases/opentelemetry.io_instrumentations.yaml b/config/crd/bases/opentelemetry.io_instrumentations.yaml index b88d086f5b..b10a5eaf4d 100644 --- a/config/crd/bases/opentelemetry.io_instrumentations.yaml +++ b/config/crd/bases/opentelemetry.io_instrumentations.yaml @@ -1037,6 +1037,30 @@ spec: - xray type: string type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic type: object status: type: object diff --git a/docs/api.md b/docs/api.md index c374b1d622..c6ca926ef6 100644 --- a/docs/api.md +++ b/docs/api.md @@ -179,6 +179,16 @@ Enum=tracecontext;baggage;b3;b3multi;jaeger;xray;ottrace;none
Sampler defines sampling configuration.
false + + selector + object + + Selector is the label selector for affected Pods. +This selector only takes effect when annotation: instrumentation.opentelemetry.io/inject-xx equal true. +Unlike standard label selectors, `nil` means `everything`, and this is also the default. +This may change in a future CRD version.
+ + false @@ -3922,6 +3932,91 @@ The value can be for instance parentbased_always_on, parentbased_always_off, par + +### Instrumentation.spec.selector +[↩ Parent](#instrumentationspec) + + + +Selector is the label selector for affected Pods. +This selector only takes effect when annotation: instrumentation.opentelemetry.io/inject-xx equal true. +Unlike standard label selectors, `nil` means `everything`, and this is also the default. +This may change in a future CRD version. + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
matchExpressions[]object + matchExpressions is a list of label selector requirements. The requirements are ANDed.
+
false
matchLabelsmap[string]string + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels +map is equivalent to an element of matchExpressions, whose key field is "key", the +operator is "In", and the values array contains only "value". The requirements are ANDed.
+
false
+ + +### Instrumentation.spec.selector.matchExpressions[index] +[↩ Parent](#instrumentationspecselector) + + + +A label selector requirement is a selector that contains values, a key, and an operator that +relates the key and values. + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDescriptionRequired
keystring + key is the label key that the selector applies to.
+
true
operatorstring + operator represents a key's relationship to a set of values. +Valid operators are In, NotIn, Exists and DoesNotExist.
+
true
values[]string + values is an array of string values. If the operator is In or NotIn, +the values array must be non-empty. If the operator is Exists or DoesNotExist, +the values array must be empty. This array is replaced during a strategic +merge patch.
+
false
+ ## OpAMPBridge [↩ Parent](#opentelemetryiov1alpha1 ) diff --git a/pkg/instrumentation/podmutator.go b/pkg/instrumentation/podmutator.go index 37d1be99b7..c388e6c908 100644 --- a/pkg/instrumentation/podmutator.go +++ b/pkg/instrumentation/podmutator.go @@ -22,6 +22,8 @@ import ( "github.com/go-logr/logr" corev1 "k8s.io/api/core/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/tools/record" "sigs.k8s.io/controller-runtime/pkg/client" @@ -372,7 +374,7 @@ func (pm *instPodMutator) getInstrumentationInstance(ctx context.Context, ns cor } if strings.EqualFold(instValue, "true") { - return pm.selectInstrumentationInstanceFromNamespace(ctx, ns) + return pm.selectInstrumentationInstanceFromNamespace(ctx, ns, pod) } var instNamespacedName types.NamespacedName @@ -391,18 +393,39 @@ func (pm *instPodMutator) getInstrumentationInstance(ctx context.Context, ns cor return otelInst, nil } -func (pm *instPodMutator) selectInstrumentationInstanceFromNamespace(ctx context.Context, ns corev1.Namespace) (*v1alpha1.Instrumentation, error) { +func (pm *instPodMutator) selectInstrumentationInstanceFromNamespace(ctx context.Context, ns corev1.Namespace, pod corev1.Pod) (*v1alpha1.Instrumentation, error) { var otelInsts v1alpha1.InstrumentationList if err := pm.Client.List(ctx, &otelInsts, client.InNamespace(ns.Name)); err != nil { return nil, err } - switch s := len(otelInsts.Items); { + // selector + var availableInstrument []v1alpha1.Instrumentation + for _, ins := range otelInsts.Items { + isMatch := true + if ins.Spec.Selector != nil { + labelSelector, err := v1.LabelSelectorAsSelector(ins.Spec.Selector) + if err != nil { + return nil, err + } + set := labels.Set(pod.GetLabels()) + // selector not match + if !labelSelector.Matches(set) { + isMatch = false + } + } + + if isMatch { + availableInstrument = append(availableInstrument, ins) + } + } + + switch s := len(availableInstrument); { case s == 0: return nil, errNoInstancesAvailable case s > 1: return nil, errMultipleInstancesPossible default: - return &otelInsts.Items[0], nil + return &availableInstrument[0], nil } } diff --git a/tests/e2e-instrumentation/instrumentation-select/00-install-collector.yaml b/tests/e2e-instrumentation/instrumentation-select/00-install-collector.yaml new file mode 100644 index 0000000000..fe390c6cae --- /dev/null +++ b/tests/e2e-instrumentation/instrumentation-select/00-install-collector.yaml @@ -0,0 +1,23 @@ +apiVersion: opentelemetry.io/v1alpha1 +kind: OpenTelemetryCollector +metadata: + name: sidecar +spec: + config: | + receivers: + otlp: + protocols: + grpc: + http: + processors: + + exporters: + debug: + + service: + pipelines: + traces: + receivers: [otlp] + processors: [] + exporters: [debug] + mode: sidecar diff --git a/tests/e2e-instrumentation/instrumentation-select/00-install-instrumentation-select.yaml b/tests/e2e-instrumentation/instrumentation-select/00-install-instrumentation-select.yaml new file mode 100644 index 0000000000..74f5aa10f3 --- /dev/null +++ b/tests/e2e-instrumentation/instrumentation-select/00-install-instrumentation-select.yaml @@ -0,0 +1,75 @@ +apiVersion: opentelemetry.io/v1alpha1 +kind: Instrumentation +metadata: + name: java-select +spec: + selector: + matchLabels: + app: my-java-select + env: + - name: OTEL_TRACES_EXPORTER + value: otlp + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://localhost:4317 + - name: OTEL_EXPORTER_OTLP_TIMEOUT + value: "20" + - name: OTEL_TRACES_SAMPLER + value: parentbased_traceidratio + - name: OTEL_TRACES_SAMPLER_ARG + value: "0.85" + - name: SPLUNK_TRACE_RESPONSE_HEADER_ENABLED + value: "true" + exporter: + endpoint: http://localhost:4317 + propagators: + - jaeger + - b3 + sampler: + type: parentbased_traceidratio + argument: "0.25" + java: + env: + - name: OTEL_JAVAAGENT_DEBUG + value: "true" + - name: OTEL_INSTRUMENTATION_JDBC_ENABLED + value: "false" + - name: SPLUNK_PROFILER_ENABLED + value: "false" +--- +apiVersion: opentelemetry.io/v1alpha1 +kind: Instrumentation +metadata: + name: my-java-multi +spec: + selector: + matchLabels: + app: my-java-multi + env: + - name: OTEL_TRACES_EXPORTER + value: otlp + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://localhost:4317 + - name: OTEL_EXPORTER_OTLP_TIMEOUT + value: "20" + - name: OTEL_TRACES_SAMPLER + value: parentbased_traceidratio + - name: OTEL_TRACES_SAMPLER_ARG + value: "0.85" + - name: SPLUNK_TRACE_RESPONSE_HEADER_ENABLED + value: "true" + exporter: + endpoint: http://localhost:4317 + propagators: + - jaeger + - b3 + sampler: + type: parentbased_traceidratio + argument: "0.25" + java: + env: + - name: OTEL_JAVAAGENT_DEBUG + value: "true" + - name: OTEL_INSTRUMENTATION_JDBC_ENABLED + value: "false" + - name: SPLUNK_PROFILER_ENABLED + value: "false" diff --git a/tests/e2e-instrumentation/instrumentation-select/01-assert-select-multi.yaml b/tests/e2e-instrumentation/instrumentation-select/01-assert-select-multi.yaml new file mode 100644 index 0000000000..be4bcdec4e --- /dev/null +++ b/tests/e2e-instrumentation/instrumentation-select/01-assert-select-multi.yaml @@ -0,0 +1,77 @@ +apiVersion: v1 +kind: Pod +metadata: + annotations: + instrumentation.opentelemetry.io/inject-java: "true" + sidecar.opentelemetry.io/inject: "true" + labels: + app: my-java-multi +spec: + containers: + - env: + - name: OTEL_NODE_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: OTEL_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: OTEL_JAVAAGENT_DEBUG + value: "true" + - name: OTEL_INSTRUMENTATION_JDBC_ENABLED + value: "false" + - name: SPLUNK_PROFILER_ENABLED + value: "false" + - name: JAVA_TOOL_OPTIONS + value: ' -javaagent:/otel-auto-instrumentation-java/javaagent.jar' + - name: OTEL_TRACES_EXPORTER + value: otlp + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://localhost:4317 + - name: OTEL_EXPORTER_OTLP_TIMEOUT + value: "20" + - name: OTEL_TRACES_SAMPLER + value: parentbased_traceidratio + - name: OTEL_TRACES_SAMPLER_ARG + value: "0.85" + - name: SPLUNK_TRACE_RESPONSE_HEADER_ENABLED + value: "true" + - name: OTEL_SERVICE_NAME + value: my-java-multi + - 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: jaeger,b3 + - 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 + - args: + - --config=env:OTEL_CONFIG + name: otc-container + initContainers: + - name: opentelemetry-auto-instrumentation-java +status: + containerStatuses: + - name: myapp + ready: true + started: true + - name: otc-container + ready: true + started: true + initContainerStatuses: + - name: opentelemetry-auto-instrumentation-java + ready: true + phase: Running diff --git a/tests/e2e-instrumentation/instrumentation-select/01-assert-select.yaml b/tests/e2e-instrumentation/instrumentation-select/01-assert-select.yaml new file mode 100644 index 0000000000..bf96c2b522 --- /dev/null +++ b/tests/e2e-instrumentation/instrumentation-select/01-assert-select.yaml @@ -0,0 +1,77 @@ +apiVersion: v1 +kind: Pod +metadata: + annotations: + instrumentation.opentelemetry.io/inject-java: "true" + sidecar.opentelemetry.io/inject: "true" + labels: + app: my-java-select +spec: + containers: + - env: + - name: OTEL_NODE_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: OTEL_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: OTEL_JAVAAGENT_DEBUG + value: "true" + - name: OTEL_INSTRUMENTATION_JDBC_ENABLED + value: "false" + - name: SPLUNK_PROFILER_ENABLED + value: "false" + - name: JAVA_TOOL_OPTIONS + value: ' -javaagent:/otel-auto-instrumentation-java/javaagent.jar' + - name: OTEL_TRACES_EXPORTER + value: otlp + - name: OTEL_EXPORTER_OTLP_ENDPOINT + value: http://localhost:4317 + - name: OTEL_EXPORTER_OTLP_TIMEOUT + value: "20" + - name: OTEL_TRACES_SAMPLER + value: parentbased_traceidratio + - name: OTEL_TRACES_SAMPLER_ARG + value: "0.85" + - name: SPLUNK_TRACE_RESPONSE_HEADER_ENABLED + value: "true" + - name: OTEL_SERVICE_NAME + value: my-java-select + - 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: jaeger,b3 + - 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 + - args: + - --config=env:OTEL_CONFIG + name: otc-container + initContainers: + - name: opentelemetry-auto-instrumentation-java +status: + containerStatuses: + - name: myapp + ready: true + started: true + - name: otc-container + ready: true + started: true + initContainerStatuses: + - name: opentelemetry-auto-instrumentation-java + ready: true + phase: Running diff --git a/tests/e2e-instrumentation/instrumentation-select/01-assert-without-select.yaml b/tests/e2e-instrumentation/instrumentation-select/01-assert-without-select.yaml new file mode 100644 index 0000000000..ea8bdf33d9 --- /dev/null +++ b/tests/e2e-instrumentation/instrumentation-select/01-assert-without-select.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Pod +metadata: + annotations: + instrumentation.opentelemetry.io/inject-java: "true" + sidecar.opentelemetry.io/inject: "true" + labels: + app: my-java-without-select +spec: + 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-select/01-install-app-select.yaml b/tests/e2e-instrumentation/instrumentation-select/01-install-app-select.yaml new file mode 100644 index 0000000000..145bd6bed8 --- /dev/null +++ b/tests/e2e-instrumentation/instrumentation-select/01-install-app-select.yaml @@ -0,0 +1,86 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-java-select +spec: + selector: + matchLabels: + app: my-java-select + replicas: 1 + template: + metadata: + labels: + app: my-java-select + annotations: + sidecar.opentelemetry.io/inject: "true" + 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"] +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-java-without-select +spec: + selector: + matchLabels: + app: my-java-without-select + replicas: 1 + template: + metadata: + labels: + app: my-java-without-select + annotations: + sidecar.opentelemetry.io/inject: "true" + 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"] +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-java-multi +spec: + selector: + matchLabels: + app: my-java-multi + replicas: 1 + template: + metadata: + labels: + app: my-java-multi + annotations: + sidecar.opentelemetry.io/inject: "true" + 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-select/chainsaw-test.yaml b/tests/e2e-instrumentation/instrumentation-select/chainsaw-test.yaml new file mode 100755 index 0000000000..3631d6e7d8 --- /dev/null +++ b/tests/e2e-instrumentation/instrumentation-select/chainsaw-test.yaml @@ -0,0 +1,40 @@ +# 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 +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: 00-install-collector.yaml + - apply: + file: 00-install-instrumentation-select.yaml + - name: step-01 + try: + - apply: + file: 01-install-app-select.yaml + - assert: + file: 01-assert*.yaml + catch: + - podLogs: + selector: app=my-java-select \ No newline at end of file