Skip to content

Commit 47d7aa7

Browse files
authored
Merge branch 'main' into maxime.chambre/allow-check-config-without-init-config
2 parents b884507 + 283e3c6 commit 47d7aa7

File tree

7 files changed

+70
-26
lines changed

7 files changed

+70
-26
lines changed

lib/saluki-components/src/common/otlp/traces/translator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ impl OtlpTracesTranslator {
5858

5959
pub fn translate_resource_spans(&self, resource_spans: ResourceSpans, metrics: &Metrics) -> Vec<Event> {
6060
let resource: OtlpResource = resource_spans.resource.unwrap_or_default();
61-
let resource_tags: TagSet = resource_attributes_to_tagset(&resource.attributes);
61+
let resource_tags = resource_attributes_to_tagset(&resource.attributes).into_shared();
6262
let mut traces_by_id: FastHashMap<u64, TraceEntry> = FastHashMap::default();
6363
let ignore_missing_fields = self.config.ignore_missing_datadog_fields;
6464

lib/saluki-components/src/common/otlp/util.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::sync::LazyLock;
77
use opentelemetry_semantic_conventions::resource::*;
88
use otlp_protos::opentelemetry::proto::common::v1::{self as otlp_common, any_value::Value};
99
use saluki_common::collections::{FastHashMap, FastHashSet};
10-
use saluki_context::tags::TagSet;
10+
use saluki_context::tags::{SharedTagSet, TagSet};
1111

1212
// ============================================================================
1313
// Datadog attribute key constants shared across the encoder and translator
@@ -144,9 +144,9 @@ pub fn extract_container_tags_from_resource_attributes(attributes: &[otlp_common
144144

145145
/// Extracts container tags from a resource tagset and inserts them into the provided TagSet.
146146
///
147-
/// This mirrors `extract_container_tags_from_resource_attributes`, but operates on a `TagSet` representation of the
148-
/// resource.
149-
pub fn extract_container_tags_from_resource_tagset(resource_tags: &TagSet, tags: &mut TagSet) {
147+
/// This mirrors `extract_container_tags_from_resource_attributes`, but operates on a `SharedTagSet` representation of
148+
/// the resource.
149+
pub fn extract_container_tags_from_resource_tagset(resource_tags: &SharedTagSet, tags: &mut TagSet) {
150150
let mut extracted_tags = FastHashSet::default();
151151

152152
for tag in resource_tags {
@@ -208,10 +208,10 @@ pub fn resource_to_source(resource: &otlp_protos::opentelemetry::proto::resource
208208
None
209209
}
210210

211-
/// Resolves the source metadata from a resource `TagSet`.
211+
/// Resolves the source metadata from a resource `SharedTagSet`.
212212
///
213213
/// This is equivalent to `resource_to_source`, but avoids the OTLP protobuf resource type.
214-
pub fn tags_to_source(resource_tags: &TagSet) -> Option<Source> {
214+
pub fn tags_to_source(resource_tags: &SharedTagSet) -> Option<Source> {
215215
let get = |key: &str| -> Option<&str> { resource_tags.get_single_tag(key).and_then(|t| t.value()) };
216216

217217
// AWS ECS Fargate

lib/saluki-components/src/encoders/datadog/traces/mod.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use opentelemetry_semantic_conventions::resource::{
1616
use protobuf::{rt::WireType, CodedOutputStream, Message};
1717
use saluki_common::task::HandleExt as _;
1818
use saluki_config::GenericConfiguration;
19-
use saluki_context::tags::TagSet;
19+
use saluki_context::tags::{SharedTagSet, TagSet};
2020
use saluki_core::data_model::event::trace::{
2121
AttributeScalarValue, AttributeValue, Span as DdSpan, SpanEvent as DdSpanEvent, SpanLink as DdSpanLink,
2222
};
@@ -774,12 +774,12 @@ fn write_map_entry_string_string(
774774
Ok(())
775775
}
776776

777-
fn get_resource_tag_value<'a>(resource_tags: &'a TagSet, key: &str) -> Option<&'a str> {
777+
fn get_resource_tag_value<'a>(resource_tags: &'a SharedTagSet, key: &str) -> Option<&'a str> {
778778
resource_tags.get_single_tag(key).and_then(|t| t.value())
779779
}
780780

781781
fn resolve_hostname<'a>(
782-
resource_tags: &'a TagSet, source: Option<&'a OtlpSource>, default_hostname: Option<&'a str>,
782+
resource_tags: &'a SharedTagSet, source: Option<&'a OtlpSource>, default_hostname: Option<&'a str>,
783783
ignore_missing_fields: bool,
784784
) -> Option<&'a str> {
785785
let mut hostname = match source {
@@ -801,7 +801,7 @@ fn resolve_hostname<'a>(
801801
hostname
802802
}
803803

804-
fn resolve_env(resource_tags: &TagSet, ignore_missing_fields: bool) -> Option<&str> {
804+
fn resolve_env(resource_tags: &SharedTagSet, ignore_missing_fields: bool) -> Option<&str> {
805805
if let Some(value) = get_resource_tag_value(resource_tags, KEY_DATADOG_ENVIRONMENT) {
806806
return Some(value);
807807
}
@@ -814,7 +814,7 @@ fn resolve_env(resource_tags: &TagSet, ignore_missing_fields: bool) -> Option<&s
814814
get_resource_tag_value(resource_tags, DEPLOYMENT_ENVIRONMENT_KEY)
815815
}
816816

817-
fn resolve_container_id<'a>(resource_tags: &'a TagSet, first_span: Option<&'a DdSpan>) -> Option<&'a str> {
817+
fn resolve_container_id<'a>(resource_tags: &'a SharedTagSet, first_span: Option<&'a DdSpan>) -> Option<&'a str> {
818818
for key in [KEY_DATADOG_CONTAINER_ID, CONTAINER_ID, K8S_POD_UID] {
819819
if let Some(value) = get_resource_tag_value(resource_tags, key) {
820820
return Some(value);
@@ -832,15 +832,15 @@ fn resolve_container_id<'a>(resource_tags: &'a TagSet, first_span: Option<&'a Dd
832832
None
833833
}
834834

835-
fn resolve_app_version(resource_tags: &TagSet) -> Option<&str> {
835+
fn resolve_app_version(resource_tags: &SharedTagSet) -> Option<&str> {
836836
if let Some(value) = get_resource_tag_value(resource_tags, KEY_DATADOG_VERSION) {
837837
return Some(value);
838838
}
839839
get_resource_tag_value(resource_tags, SERVICE_VERSION)
840840
}
841841

842842
fn resolve_container_tags(
843-
resource_tags: &TagSet, source: Option<&OtlpSource>, ignore_missing_fields: bool,
843+
resource_tags: &SharedTagSet, source: Option<&OtlpSource>, ignore_missing_fields: bool,
844844
) -> Option<MetaString> {
845845
// TODO: some refactoring is probably needed to normalize this function, the tags should already be normalized
846846
// since we do so when we transform OTLP spans to DD spans however to make this class extensible for non otlp traces, we would

lib/saluki-components/src/transforms/apm_stats/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ fn now_nanos() -> u64 {
425425
}
426426

427427
/// Resolves container ID from OTLP resource tags.
428-
fn resolve_container_id(resource_tags: &TagSet) -> MetaString {
428+
fn resolve_container_id(resource_tags: &SharedTagSet) -> MetaString {
429429
for key in [KEY_DATADOG_CONTAINER_ID, CONTAINER_ID, K8S_POD_UID] {
430430
if let Some(tag) = resource_tags.get_single_tag(key) {
431431
if let Some(value) = tag.value() {
@@ -440,7 +440,7 @@ fn resolve_container_id(resource_tags: &TagSet) -> MetaString {
440440
}
441441

442442
/// Extracts container tags from OTLP resource tags.
443-
fn extract_container_tags(resource_tags: &TagSet) -> SharedTagSet {
443+
fn extract_container_tags(resource_tags: &SharedTagSet) -> SharedTagSet {
444444
let mut container_tags_set = TagSet::default();
445445
extract_container_tags_from_resource_tagset(resource_tags, &mut container_tags_set);
446446

lib/saluki-config/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ serde_json = { workspace = true }
1616
serde_yaml = { workspace = true }
1717
snafu = { workspace = true }
1818
tempfile = { workspace = true }
19-
tokio = { workspace = true, features = ["fs", "io-util", "process", "time"] }
19+
tokio = { workspace = true, features = ["fs", "io-util", "process", "sync", "time"] }
2020
tracing = { workspace = true }
21+
2122
[dev-dependencies]
2223
tokio = { workspace = true, features = ["macros", "rt"] }

lib/saluki-config/src/lib.rs

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -334,20 +334,20 @@ impl ConfigurationLoader {
334334
/// Care should be taken to not return sensitive information in either the error output (standard error) of the
335335
/// backend command or the `error` field in the JSON response, as these values are logged in order to aid debugging.
336336
pub async fn with_default_secrets_resolution(mut self) -> Result<Self, ConfigurationError> {
337-
let initial_figment = build_figment_from_sources(&self.provider_sources);
337+
let configuration = build_figment_from_sources(&self.provider_sources);
338338

339339
// If no secrets backend is set, we can't resolve secrets, so just return early.
340-
if !initial_figment.contains("secret_backend_command") {
340+
if !has_valid_secret_backend_command(&configuration) {
341341
debug!("No secrets backend configured; skipping secrets resolution.");
342342
return Ok(self);
343343
}
344344

345-
let resolver_config = initial_figment.extract::<secrets::resolver::ExternalProcessResolverConfiguration>()?;
345+
let resolver_config = configuration.extract::<secrets::resolver::ExternalProcessResolverConfiguration>()?;
346346
let resolver = secrets::resolver::ExternalProcessResolver::from_configuration(resolver_config)
347347
.await
348348
.context(Secrets)?;
349349

350-
let provider = secrets::Provider::new(resolver, &initial_figment)
350+
let provider = secrets::Provider::new(resolver, &configuration)
351351
.await
352352
.context(Secrets)?;
353353

@@ -856,10 +856,53 @@ fn from_figment_error(lookup_sources: &HashSet<LookupSource>, e: figment::Error)
856856
}
857857
}
858858

859+
fn has_valid_secret_backend_command(configuration: &Figment) -> bool {
860+
configuration
861+
.find_value("secret_backend_command")
862+
.ok()
863+
.is_some_and(|v| v.as_str().filter(|s| !s.is_empty()).is_some())
864+
}
865+
859866
#[cfg(test)]
860867
mod tests {
861868
use super::*;
862869

870+
macro_rules! json_to_figment {
871+
($json:tt) => {
872+
Figment::from(Serialized::defaults(serde_json::json!($json)))
873+
};
874+
}
875+
876+
#[test]
877+
fn test_has_valid_secret_backend_command() {
878+
// When `secrets_backend_command` is not set at all, or is set to an empty string, or isn't even a string
879+
// value... then we should consider those scenarios as "secrets backend not configured".
880+
let figment = Figment::new();
881+
assert!(!has_valid_secret_backend_command(&figment));
882+
883+
let figment = json_to_figment!({
884+
"secret_backend_command": ""
885+
});
886+
assert!(!has_valid_secret_backend_command(&figment));
887+
888+
let figment = json_to_figment!({
889+
"secret_backend_command": false
890+
});
891+
assert!(!has_valid_secret_backend_command(&figment));
892+
893+
// Otherwise, whether it's a valid path or not, then we should consider things enabled, which means we'll
894+
// at least attempt secrets resolution:
895+
let figment = json_to_figment!({
896+
"secret_backend_command": "/usr/bin/foo"
897+
});
898+
assert!(has_valid_secret_backend_command(&figment));
899+
900+
let figment = json_to_figment!({
901+
"secret_backend_command": "or anything else"
902+
});
903+
assert!(has_valid_secret_backend_command(&figment));
904+
}
905+
863906
#[tokio::test]
864907
async fn test_static_configuration() {
865908
let (cfg, _) = ConfigurationLoader::for_tests(

lib/saluki-core/src/data_model/event/trace/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Traces.
22
33
use saluki_common::collections::FastHashMap;
4-
use saluki_context::tags::TagSet;
4+
use saluki_context::tags::SharedTagSet;
55
use stringtheory::MetaString;
66

77
/// Trace-level sampling metadata.
@@ -61,7 +61,7 @@ pub struct Trace {
6161
/// Resource-level tags associated with this trace.
6262
///
6363
/// This is derived from the resource of the spans and used to construct the tracer payload.
64-
resource_tags: TagSet,
64+
resource_tags: SharedTagSet,
6565
/// Trace-level sampling metadata.
6666
///
6767
/// This field contains sampling decision information (priority, decision maker, rates)
@@ -72,10 +72,10 @@ pub struct Trace {
7272

7373
impl Trace {
7474
/// Creates a new `Trace` with the given spans.
75-
pub fn new(spans: Vec<Span>, resource_tags: TagSet) -> Self {
75+
pub fn new(spans: Vec<Span>, resource_tags: impl Into<SharedTagSet>) -> Self {
7676
Self {
7777
spans,
78-
resource_tags,
78+
resource_tags: resource_tags.into(),
7979
sampling: None,
8080
}
8181
}
@@ -124,7 +124,7 @@ impl Trace {
124124
}
125125

126126
/// Returns the resource-level tags associated with this trace.
127-
pub fn resource_tags(&self) -> &TagSet {
127+
pub fn resource_tags(&self) -> &SharedTagSet {
128128
&self.resource_tags
129129
}
130130

0 commit comments

Comments
 (0)