Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
223 changes: 159 additions & 64 deletions Cargo.lock

Large diffs are not rendered by default.

21 changes: 20 additions & 1 deletion libdd-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
#![cfg_attr(not(test), deny(clippy::unimplemented))]

use anyhow::Context;
use http::uri;
use http::uri::PathAndQuery;
use http::{uri, Uri};
use serde::de::Error;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::sync::{Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard};
Expand Down Expand Up @@ -332,6 +333,24 @@ impl Endpoint {
/// Default value for the timeout field in milliseconds.
pub const DEFAULT_TIMEOUT: u64 = 3_000;

pub fn agentless(site: &str, api_key: String) -> anyhow::Result<Self> {
Ok(Self {
url: Uri::builder()
.scheme("https")
.authority(
uri::Authority::try_from(site)
.with_context(|| format!("dd_site is an invalid url: {site}"))?,
)
.path_and_query(PathAndQuery::from_static(""))
.build()
.unwrap(),
api_key: Some(api_key.into()),
timeout_ms: Self::DEFAULT_TIMEOUT,
test_token: None,
use_system_resolver: true,
})
}

/// Returns an iterator of optional endpoint-specific headers (api-key, test-token)
/// as (header_name, header_value) string tuples for any that are available.
pub fn get_optional_headers(&self) -> impl Iterator<Item = (&'static str, &str)> {
Expand Down
17 changes: 13 additions & 4 deletions libdd-remote-config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ client = [
"tokio-util",
"manual_future",
"time",
"tracing"
"tracing",
]

regex-lite = ["libdd-common/regex-lite"]
Expand All @@ -36,24 +36,33 @@ test = ["hyper/server", "hyper-util"]
[dependencies]
anyhow = { version = "1.0" }
libdd-common = { path = "../libdd-common", version = "4.2.0", default-features = false }
libdd-capabilities = { path = "../libdd-capabilities" }
libdd-capabilities-impl = { version = "2.0.0", path = "../libdd-capabilities-impl", features = ["https"]}
libdd-trace-protobuf = { path = "../libdd-trace-protobuf", version = "3.0.2", optional = true }
hyper = { workspace = true, optional = true, default-features = false }
http-body-util = {version = "0.1", optional = true }
http-body-util = { version = "0.1", optional = true }
http = { version = "1.1", optional = true }
base64 = { version = "0.22.1", optional = true }
sha2 = { version = "0.10", optional = true }
uuid = { version = "1.7.0", features = ["v4"], optional = true }
futures-util = { version = "0.3", optional = true }
tokio = { version = "1.36.0", optional = true }
tokio-util = { version = "0.7.10", optional = true }
tokio-util = { version = "0.7.10", optional = true }
manual_future = { version = "0.1.1", optional = true }
time = { version = "0.3", features = ["parsing", "serde", "formatting"], optional = true }
time = { version = "0.3", features = [
"parsing",
"serde",
"formatting",
], optional = true }
tracing = { version = "0.1", default-features = false, optional = true }
serde = "1.0"
serde_json = { version = "1.0", features = ["raw_value"] }
serde_with = "3"
thiserror = "2"
hashbrown = "0.15"
tuf = { git = "https://github.com/DataDog/rust-tuf/", tag = "0.3.0-beta10-opw-3" }
prost = "0.14.1"
futures = "0.3"

# Test feature
hyper-util = { workspace = true, features = ["service"], optional = true }
Expand Down
52 changes: 44 additions & 8 deletions libdd-remote-config/examples/remote_config_fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use libdd_remote_config::file_change_tracker::{Change, FilePath};
use libdd_remote_config::file_storage::ParsedFileStorage;
use libdd_remote_config::RemoteConfigProduct::ApmTracing;
use libdd_remote_config::{RemoteConfigParsed, Target};
use std::process::Command;
use std::time::Duration;
use tokio::time::sleep;

Expand All @@ -16,8 +17,45 @@ const SERVICE: &str = "testservice";
const ENV: &str = "testenv";
const VERSION: &str = "1.2.3";

fn get_hostname() -> String {
Command::new("hostname")
.output()
.ok()
.and_then(|o| String::from_utf8(o.stdout).ok())
.map(|s| s.trim().to_string())
.unwrap_or_else(|| "unknown".to_string())
}

#[tokio::main(flavor = "current_thread")]
async fn main() {
let hostname = get_hostname();
println!("Hostname: {hostname}");

let dd_api_key = std::env::var("DD_API_KEY").ok();
let dd_site = std::env::var("DD_SITE").ok();

let (endpoint, agentless_enabled) = match (dd_api_key, dd_site) {
(Some(api_key), Some(site)) => {
println!("DD_API_KEY and DD_SITE are set — enabling agentless mode (site: {site})");
let endpoint = Endpoint::agentless(&site, api_key)
.expect("Failed to build agentless endpoint from DD_SITE");
(endpoint, true)
}
_ => {
println!("DD_API_KEY / DD_SITE not set — connecting to local agent");
(
Endpoint {
url: http::Uri::from_static("http://localhost:8126"),
api_key: None,
timeout_ms: 5000, // custom timeout, defaults to 3 seconds
test_token: None,
..Default::default()
},
false,
)
}
};

// SingleChangesFetcher is ideal for a single static (runtime_id, service, env, version) tuple
// Otherwise a SharedFetcher (or even a MultiTargetFetcher for a potentially high number of
// targets) for multiple targets is needed. These can be manually wired together with a
Expand All @@ -40,18 +78,16 @@ async fn main() {
invariants: ConfigInvariants {
language: "awesomelang".to_string(),
tracer_version: "99.10.5".to_string(),
endpoint: Endpoint {
url: http::Uri::from_static("http://localhost:8126"),
api_key: None,
timeout_ms: 5000, // custom timeout, defaults to 3 seconds
test_token: None,
..Default::default()
},
endpoint,
hostname,
agentless_enabled,
},
products: vec![ApmTracing],
capabilities: vec![],
},
);
)
.await
.expect("Failed to create SingleChangesFetcher");

loop {
match fetcher.fetch_changes().await {
Expand Down
63 changes: 63 additions & 0 deletions libdd-remote-config/roots/prod/config_root.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
"signed": {
"_type": "root",
"spec_version": "1.0",
"version": 16,
"expires": "2026-10-31T17:00:00Z",
"keys": {
"620dacb7dc843acc731e4483c24ceb4121f4de5545f92d15dc2b13299b660e01": {
"keytype": "ed25519",
"scheme": "ed25519",
"keyid_hash_algorithms": ["sha256", "sha512"],
"keyval": { "public": "91d413c791907aae0be739d94a1e5e59c5d5ba65a8bbc1fb2153a5680f2d5958" }
},
"e1fdd5827bb44defe9b87ed835c854be4b78a86ded013d1646bc416c1c89a9db": {
"keytype": "ed25519",
"scheme": "ed25519",
"keyid_hash_algorithms": ["sha256", "sha512"],
"keyval": { "public": "9323800f89d833ee263d3661c2616da89e405b92beeec334f21d54b5f60fbd85" }
}
},
"roles": {
"root": {
"keyids": [
"620dacb7dc843acc731e4483c24ceb4121f4de5545f92d15dc2b13299b660e01",
"e1fdd5827bb44defe9b87ed835c854be4b78a86ded013d1646bc416c1c89a9db"
],
"threshold": 2
},
"snapshot": {
"keyids": [
"620dacb7dc843acc731e4483c24ceb4121f4de5545f92d15dc2b13299b660e01",
"e1fdd5827bb44defe9b87ed835c854be4b78a86ded013d1646bc416c1c89a9db"
],
"threshold": 2
},
"targets": {
"keyids": [
"620dacb7dc843acc731e4483c24ceb4121f4de5545f92d15dc2b13299b660e01",
"e1fdd5827bb44defe9b87ed835c854be4b78a86ded013d1646bc416c1c89a9db"
],
"threshold": 2
},
"timestamp": {
"keyids": [
"620dacb7dc843acc731e4483c24ceb4121f4de5545f92d15dc2b13299b660e01",
"e1fdd5827bb44defe9b87ed835c854be4b78a86ded013d1646bc416c1c89a9db"
],
"threshold": 2
}
},
"consistent_snapshot": true
},
"signatures": [
{
"keyid": "620dacb7dc843acc731e4483c24ceb4121f4de5545f92d15dc2b13299b660e01",
"sig": "a8b4ee59576c82bc1bc944df014bbeb90f5cba4ffbd8b7878461da2c934fd3bf93ac4c3b85a7936584da4a5a0cfe93b7150b559fc96423a98a70a11fc844f208"
},
{
"keyid": "e1fdd5827bb44defe9b87ed835c854be4b78a86ded013d1646bc416c1c89a9db",
"sig": "3332e240a023dc267e87e210c7b46b9fa5772932d84936e3a7a5b5018b0f45fbf068ce60b97beb6e7e6c0c12a68d68a44461e590a934b577c71d4ff6dd94db09"
}
]
}
63 changes: 63 additions & 0 deletions libdd-remote-config/roots/prod/director_root.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{
"signed": {
"_type": "root",
"spec_version": "1.0",
"version": 15,
"expires": "2026-10-31T17:00:00Z",
"keys": {
"44d70fa8eae4c07f26c2767270827b6b9e11e7972926b3b419b5ea14ec32f796": {
"keytype": "ed25519",
"scheme": "ed25519",
"keyid_hash_algorithms": ["sha256", "sha512"],
"keyval": { "public": "286d6ae328365afec0f92519ceab68cd627e34072cde90b2f5d167badea970f2" }
},
"b2b93a6dccc96d053e6db39181124c85ba4156d43503d4351b5500316fa084e8": {
"keytype": "ed25519",
"scheme": "ed25519",
"keyid_hash_algorithms": ["sha256", "sha512"],
"keyval": { "public": "afdd68be53815d67f8fa99cf101aac4589a358c660adf7dd4e179fe96834d3c9" }
}
},
"roles": {
"root": {
"keyids": [
"44d70fa8eae4c07f26c2767270827b6b9e11e7972926b3b419b5ea14ec32f796",
"b2b93a6dccc96d053e6db39181124c85ba4156d43503d4351b5500316fa084e8"
],
"threshold": 2
},
"snapshot": {
"keyids": [
"44d70fa8eae4c07f26c2767270827b6b9e11e7972926b3b419b5ea14ec32f796",
"b2b93a6dccc96d053e6db39181124c85ba4156d43503d4351b5500316fa084e8"
],
"threshold": 2
},
"targets": {
"keyids": [
"44d70fa8eae4c07f26c2767270827b6b9e11e7972926b3b419b5ea14ec32f796",
"b2b93a6dccc96d053e6db39181124c85ba4156d43503d4351b5500316fa084e8"
],
"threshold": 2
},
"timestamp": {
"keyids": [
"44d70fa8eae4c07f26c2767270827b6b9e11e7972926b3b419b5ea14ec32f796",
"b2b93a6dccc96d053e6db39181124c85ba4156d43503d4351b5500316fa084e8"
],
"threshold": 2
}
},
"consistent_snapshot": true
},
"signatures": [
{
"keyid": "b2b93a6dccc96d053e6db39181124c85ba4156d43503d4351b5500316fa084e8",
"sig": "ccbe8cdd7dfb9a9d6b4bef8075a7aaf9baafe69a07100f22c04677a9737a23b24055ac3a0776c7021ae6a2fd175a251c0604164ea6705a0a896844766d2ecd07"
},
{
"keyid": "44d70fa8eae4c07f26c2767270827b6b9e11e7972926b3b419b5ea14ec32f796",
"sig": "068a2e37e93688702e75ebb328b74cd8879832a63179ba1c54976aae4ee03a5e936c7b7274d4a6aa6755c27cfe800097984d94c83be901bde72103dccebcc008"
}
]
}
Loading
Loading