diff --git a/opentelemetry-resource-detectors/src/k8s.rs b/opentelemetry-resource-detectors/src/k8s.rs new file mode 100644 index 00000000..e456efca --- /dev/null +++ b/opentelemetry-resource-detectors/src/k8s.rs @@ -0,0 +1,24 @@ +use opentelemetry::sdk::resource::{Resource, ResourceDetector}; +use opentelemetry_semantic_conventions::resource; +use std::env; +use std::time::Duration; + +/// A resource detector for Kubernetes environment variables. +pub struct K8sResourceDetector; + +impl ResourceDetector for K8sResourceDetector { + /// Detect Kubernetes-related environment variables and return a Resource. + fn detect(&self, _timeout: Duration) -> Resource { + // Attempt to read Kubernetes-specific environment variables. + let pod_name = env::var("K8S_POD_NAME").unwrap_or_else(|_| "unknown_pod".to_string()); + let namespace_name = env::var("K8S_NAMESPACE_NAME").unwrap_or_else(|_| "unknown_namespace".to_string()); + let node_name = env::var("K8S_NODE_NAME").unwrap_or_else(|_| "unknown_node".to_string()); + + // Create a Resource with Kubernetes attributes. + Resource::new(vec![ + resource::K8S_POD_NAME.string(pod_name), + resource::K8S_NAMESPACE_NAME.string(namespace_name), + resource::K8S_NODE_NAME.string(node_name), + ]) + } +} diff --git a/opentelemetry-resource-detectors/src/k8stest.rs b/opentelemetry-resource-detectors/src/k8stest.rs new file mode 100644 index 00000000..255eeb90 --- /dev/null +++ b/opentelemetry-resource-detectors/src/k8stest.rs @@ -0,0 +1,58 @@ +#[cfg(test)] +mod tests { + use super::*; + use std::time::Duration; + use temp_env; + + #[test] + fn test_k8s_resource_detector_with_env_vars() { + // Temporarily set environment variables for the test + temp_env::with_vars( + [ + ("K8S_POD_NAME", Some("test-pod")), + ("K8S_NAMESPACE_NAME", Some("test-namespace")), + ("K8S_NODE_NAME", Some("test-node")), + ], + || { + // Create the K8sResourceDetector + let detector = K8sResourceDetector::new(); + // Use the detector to fetch the resources + let resource = detector.detect(Duration::from_secs(5)); + + // Assert that the detected resource attributes match the expected values + assert_eq!( + resource, + Resource::new(vec![ + KeyValue::new("k8s.pod.name", "test-pod"), + KeyValue::new("k8s.namespace.name", "test-namespace"), + KeyValue::new("k8s.node.name", "test-node"), + ]) + ); + }, + ); + } + + #[test] + fn test_k8s_resource_detector_with_missing_env_vars() { + // Temporarily set only one environment variable to test defaults + temp_env::with_vars( + [("K8S_POD_NAME", Some("test-pod"))], + || { + // Create the K8sResourceDetector + let detector = K8sResourceDetector::new(); + // Use the detector to fetch the resources + let resource = detector.detect(Duration::from_secs(5)); + + // Assert that missing values use the default "unknown" values + assert_eq!( + resource, + Resource::new(vec![ + KeyValue::new("k8s.pod.name", "test-pod"), + KeyValue::new("k8s.namespace.name", "unknown_namespace"), + KeyValue::new("k8s.node.name", "unknown_node"), + ]) + ); + }, + ); + } +}