From f9d583ea6fe84a2ad9d427f5f40a630427d0bade Mon Sep 17 00:00:00 2001 From: Praful Khanduri <99384392+Horiodino@users.noreply.github.com> Date: Sat, 17 Feb 2024 20:29:35 +0530 Subject: [PATCH] added: tests --- pkg/constants/env.go | 8 +- pkg/instrumentation/sdk.go | 181 ++------------------------------ pkg/instrumentation/sdk_test.go | 102 ++++++++++++++++++ 3 files changed, 115 insertions(+), 176 deletions(-) diff --git a/pkg/constants/env.go b/pkg/constants/env.go index 4fa9f7f1fc..4ad7d1f326 100644 --- a/pkg/constants/env.go +++ b/pkg/constants/env.go @@ -31,8 +31,8 @@ const ( AnnotationDefaultAutoInstrumentationApacheHttpd = InstrumentationPrefix + "default-auto-instrumentation-apache-httpd-image" AnnotationDefaultAutoInstrumentationNginx = InstrumentationPrefix + "default-auto-instrumentation-nginx-image" - EnvPodName = "OTEL_RESOURCE_ATTRIBUTES_POD_NAME" - EnvPodUID = "OTEL_RESOURCE_ATTRIBUTES_POD_UID" - EnvNodeName = "OTEL_RESOURCE_ATTRIBUTES_NODE_NAME" - ReservedNamespace = "opentelemetry.io" + EnvPodName = "OTEL_RESOURCE_ATTRIBUTES_POD_NAME" + EnvPodUID = "OTEL_RESOURCE_ATTRIBUTES_POD_UID" + EnvNodeName = "OTEL_RESOURCE_ATTRIBUTES_NODE_NAME" + ReservedNamespace = "resource.opentelemetry.io/" ) diff --git a/pkg/instrumentation/sdk.go b/pkg/instrumentation/sdk.go index bfaa157844..ddd819de0f 100644 --- a/pkg/instrumentation/sdk.go +++ b/pkg/instrumentation/sdk.go @@ -30,13 +30,11 @@ import ( "go.opentelemetry.io/otel/attribute" semconv "go.opentelemetry.io/otel/semconv/v1.7.0" appsv1 "k8s.io/api/apps/v1" - v1obj "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/client-go/kubernetes" "k8s.io/client-go/util/retry" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -404,176 +402,6 @@ func chooseServiceVersion(pod corev1.Pod, index int) string { return tag } -func getAllResourceLabels(ctx context.Context, clientset kubernetes.Interface) map[string]string { - labels := make(map[string]string) - - resources := []string{"pods", "services", "deployments"} - - // use all namespaces - - ns, err := clientset.CoreV1().Namespaces().List(context.Background(), metav1.ListOptions{}) - if err != nil { - panic(err.Error()) - } - - for _, n := range ns.Items { - for _, resource := range resources { - switch resource { - case "pods": - pods, err := clientset.CoreV1().Pods(n.Name).List(context.Background(), metav1.ListOptions{}) - if err != nil { - fmt.Printf("Error fetching pods: %v\n", err) - continue - } - - extLabels := extractLabelsFromPods(pods.Items) - for key, value := range extLabels { - labels[key] = value - } - - case "services": - services, err := clientset.CoreV1().Services(n.Name).List(context.Background(), metav1.ListOptions{}) - if err != nil { - fmt.Printf("Error fetching services: %v\n", err) - continue - } - - extLabels := extractLabelsFromServices(services.Items) - for key, value := range extLabels { - labels[key] = value - } - - case "deployments": - deployments, err := clientset.AppsV1().Deployments(n.Name).List(context.Background(), metav1.ListOptions{}) - if err != nil { - panic(err.Error()) - } - - extLabels := extractLabelsFromDeployments(deployments.Items) - for key, value := range extLabels { - labels[key] = value - } - - case "statefulsets": - statefulSets, err := clientset.AppsV1().StatefulSets(n.Name).List(context.Background(), metav1.ListOptions{}) - if err != nil { - panic(err.Error()) - } - - extLabels := extractLabelsFromStatefulSets(statefulSets.Items) - for key, value := range extLabels { - labels[key] = value - } - - case "daemonsets": - daemonSets, err := clientset.AppsV1().DaemonSets(n.Name).List(context.Background(), metav1.ListOptions{}) - if err != nil { - panic(err.Error()) - } - - extLabels := extractLabelsFromDaemonSets(daemonSets.Items) - for key, value := range extLabels { - labels[key] = value - } - - case "replicasets": - replicaSets, err := clientset.AppsV1().ReplicaSets(n.Name).List(context.Background(), metav1.ListOptions{}) - if err != nil { - panic(err.Error()) - } - - extLabels := extractLabelsFromReplicaSets(replicaSets.Items) - for key, value := range extLabels { - labels[key] = value - } - - default: - fmt.Println("resource not supported") - } - } - } - - return labels -} - -func extractLabelsFromPods(pods []corev1.Pod) map[string]string { - res := make(map[string]string) - for _, pod := range pods { - for key, _ := range pod.ObjectMeta.Labels { - if strings.HasPrefix(key, constants.ReservedNamespace) { - res["pod/"+pod.Namespace] = pod.Name - } - } - } - - return res -} - -func extractLabelsFromServices(services []corev1.Service) map[string]string { - res := make(map[string]string) - for _, service := range services { - for key, _ := range service.ObjectMeta.Labels { - if strings.HasPrefix(key, constants.ReservedNamespace) { - res["service/"+service.Namespace] = service.Name - } - } - } - - return res -} - -func extractLabelsFromDeployments(deployments []v1obj.Deployment) map[string]string { - res := make(map[string]string) - for _, deployment := range deployments { - for key, _ := range deployment.ObjectMeta.Labels { - if strings.HasPrefix(key, constants.ReservedNamespace) { - res["deployment/"+deployment.Namespace] = deployment.Name - } - } - } - - return res -} - -func extractLabelsFromStatefulSets(statefulSets []v1obj.StatefulSet) map[string]string { - res := make(map[string]string) - for _, statefulSet := range statefulSets { - for key, _ := range statefulSet.ObjectMeta.Labels { - if strings.HasPrefix(key, constants.ReservedNamespace) { - res["statefulset/"+statefulSet.Namespace] = statefulSet.Name - } - } - } - - return res -} - -func extractLabelsFromDaemonSets(daemonSets []v1obj.DaemonSet) map[string]string { - res := make(map[string]string) - for _, daemonSet := range daemonSets { - for key, _ := range daemonSet.ObjectMeta.Labels { - if strings.HasPrefix(key, constants.ReservedNamespace) { - res["daemonset/"+daemonSet.Namespace] = daemonSet.Name - } - } - } - - return res -} - -func extractLabelsFromReplicaSets(replicaSets []v1obj.ReplicaSet) map[string]string { - res := make(map[string]string) - for _, replicaSet := range replicaSets { - for key, _ := range replicaSet.ObjectMeta.Labels { - if strings.HasPrefix(key, "opentelemetry.io/") { - res["replicaset/"+replicaSet.Namespace] = replicaSet.Name - } - } - } - - return res -} - // creates the service.instance.id following the semantic defined by // https://github.com/open-telemetry/semantic-conventions/pull/312. func createServiceInstanceId(namespaceName, podName, containerName string) string { @@ -623,6 +451,15 @@ func (i *sdkInjector) createResourceMap(ctx context.Context, otelinst v1alpha1.I res[string(k)] = v } } + + for k, v := range pod.GetAnnotations() { + if strings.HasPrefix(k, constants.ReservedNamespace) { + key := strings.TrimSpace(strings.TrimPrefix(k, constants.ReservedNamespace)) + if _, ok := res[key]; !ok { + res[key] = v + } + } + } return res } diff --git a/pkg/instrumentation/sdk_test.go b/pkg/instrumentation/sdk_test.go index 013a5ffc37..7b2e1d168f 100644 --- a/pkg/instrumentation/sdk_test.go +++ b/pkg/instrumentation/sdk_test.go @@ -473,6 +473,108 @@ func TestSDKInjection(t *testing.T) { }, }, }, + { + name: "Resource attribute propagate", + inst: v1alpha1.Instrumentation{ + Spec: v1alpha1.InstrumentationSpec{ + Exporter: v1alpha1.Exporter{ + Endpoint: "https://collector:4317", + }, + Resource: v1alpha1.Resource{ + Attributes: map[string]string{ + "fromcr": "val", + }, + }, + Propagators: []v1alpha1.Propagator{"jaeger"}, + Sampler: v1alpha1.Sampler{ + Type: "parentbased_traceidratio", + Argument: "0.25", + }, + }, + }, + pod: corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + "resource.opentelemetry.io/fromtest": "val", + "resource.opentelemetry.io/foo": "test", + }, + Namespace: "project1", + Name: "app", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Image: "app:latest", + Env: []corev1.EnvVar{ + { + Name: "OTEL_SERVICE_NAME", + Value: "explicitly_set", + }, + { + Name: "OTEL_EXPORTER_OTLP_ENDPOINT", + Value: "explicitly_set", + }, + { + Name: "OTEL_PROPAGATORS", + Value: "b3", + }, + { + Name: "OTEL_TRACES_SAMPLER", + Value: "always_on", + }, + { + Name: "OTEL_RESOURCE_ATTRIBUTES", + Value: "foo=bar,k8s.container.name=other,service.version=explicitly_set,", + }, + }, + }, + }, + }, + }, + expected: corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "project1", + Name: "app", + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Image: "app:latest", + Env: []corev1.EnvVar{ + { + Name: "OTEL_SERVICE_NAME", + Value: "explicitly_set", + }, + { + Name: "OTEL_EXPORTER_OTLP_ENDPOINT", + Value: "explicitly_set", + }, + { + Name: "OTEL_PROPAGATORS", + Value: "b3", + }, + { + Name: "OTEL_TRACES_SAMPLER", + Value: "always_on", + }, + { + Name: "OTEL_RESOURCE_ATTRIBUTES_NODE_NAME", + ValueFrom: &corev1.EnvVarSource{ + FieldRef: &corev1.ObjectFieldSelector{ + FieldPath: "spec.nodeName", + }, + }, + }, + { + Name: "OTEL_RESOURCE_ATTRIBUTES", + Value: "foo=bar,k8s.container.name=other,service.version=explicitly_set,fromcr=val,k8s.namespace.name=project1,k8s.node.name=$(OTEL_RESOURCE_ATTRIBUTES_NODE_NAME),k8s.pod.name=app,fromtest=val", + }, + }, + }, + }, + }, + }, + }, } for _, test := range tests {