Skip to content
Open
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
12 changes: 12 additions & 0 deletions .github/workflows/build-datadog-serverless-compat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ on:
runner:
required: true
type: string
version:
required: false
type: string

jobs:
setup:
Expand All @@ -27,6 +30,15 @@ jobs:
runs-on: ${{ inputs.runner }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Embed Serverless Compat version
shell: bash
env:
INPUT_VERSION: ${{ inputs.version }}
run: |
VERSION="$(./scripts/resolve-serverless-compat-version.sh "$INPUT_VERSION")"
if [[ -n "$VERSION" ]]; then
echo "DD_SERVERLESS_COMPAT_VERSION=$VERSION" >> "$GITHUB_ENV"
fi
- name: Install Protoc Binary
shell: bash
run: chmod +x ./scripts/install-protoc.sh && ./scripts/install-protoc.sh $HOME
Expand Down
8 changes: 3 additions & 5 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ jobs:
uses: ./.github/workflows/build-datadog-serverless-compat.yml
with:
runner: ${{ matrix.runner }}
version: ${{ inputs.version }}

package:
runs-on: ubuntu-24.04
Expand Down Expand Up @@ -65,11 +66,8 @@ jobs:
env:
INPUT_VERSION: ${{ inputs.version }}
run: |
if [[ "$GITHUB_REF" == refs/tags/datadog-serverless-compat/v* ]]; then
VERSION="${GITHUB_REF#refs/tags/datadog-serverless-compat/v}"
elif [[ -n "$INPUT_VERSION" ]]; then
VERSION="$INPUT_VERSION"
else
VERSION="$(./scripts/resolve-serverless-compat-version.sh "$INPUT_VERSION")"
if [[ -z "$VERSION" ]]; then
echo "Error: version input is required when not running on a datadog-serverless-compat/v<x.y.z> tag"
exit 1
fi
Expand Down
11 changes: 9 additions & 2 deletions .github/workflows/release-datadog-serverless-compat.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
name: Release Datadog Serverless Compat

on: workflow_dispatch
on:
workflow_dispatch:
inputs:
version:
description: "Serverless Compat release version"
required: true
type: string

permissions: {}

Expand All @@ -12,7 +18,8 @@ jobs:
runner: [ubuntu-24.04, windows-2022]
uses: ./.github/workflows/build-datadog-serverless-compat.yml
with:
runner: ${{matrix.runner}}
runner: ${{ matrix.runner }}
version: ${{ inputs.version }}
release:
runs-on: ubuntu-24.04
needs: build
Expand Down
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/datadog-serverless-compat/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ windows-enhanced-metrics = ["datadog-metrics-collector/windows-enhanced-metrics"
[dependencies]
datadog-logs-agent = { path = "../datadog-logs-agent" }
datadog-metrics-collector = { path = "../datadog-metrics-collector" }
inventory = { path = "../inventory" }
datadog-trace-agent = { path = "../datadog-trace-agent" }
libdd-trace-utils = { workspace = true, features = ["https"] }
datadog-fips = { path = "../datadog-fips", default-features = false }
Expand Down
18 changes: 18 additions & 0 deletions crates/datadog-serverless-compat/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ use datadog_metrics_collector::azure_cpu::CpuMetricsCollector;

use libdd_trace_utils::{config_utils::read_cloud_env, trace_utils::EnvironmentType};

use inventory::run_inventory_reporter;

use datadog_fips::reqwest_adapter::create_reqwest_client_builder;
use datadog_logs_agent::{
AggregatorHandle as LogAggregatorHandle, AggregatorService as LogAggregatorService,
Expand Down Expand Up @@ -161,6 +163,22 @@ pub async fn main() {

debug!("Logging subsystem enabled");

// Inventory runs independently from traces and metrics so failures cannot
// block mini-agent startup or request handling.
let inventory_api_key = dd_api_key.clone();
let inventory_site = dd_site.clone();
let inventory_proxy = https_proxy.clone();
let inventory_env = env_type.clone();
tokio::spawn(async move {
run_inventory_reporter(
inventory_api_key.as_deref(),
&inventory_site,
inventory_proxy.as_deref(),
inventory_env,
)
.await;
});

let env_verifier = Arc::new(env_verifier::ServerlessEnvVerifier::default());

let config = match config::Config::new() {
Expand Down
4 changes: 3 additions & 1 deletion crates/inventory/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ license.workspace = true
description = "Fleet Automation inventory reporter for the Serverless Compat"

[dependencies]
datadog-fips = { path = "../datadog-fips" }
libdd-common = { workspace = true }
libdd-trace-utils = { workspace = true }
reqwest = { version = "0.12", default-features = false }
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
tokio = { version = "1", features = ["macros"] }
tokio = { version = "1", features = ["macros", "time"] }
tracing = "0.1"
uuid = { version = "1", default-features = false, features = ["v4"] }

[dev-dependencies]
httpmock = "0.8"
Expand Down
29 changes: 12 additions & 17 deletions crates/inventory/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@

mod payload;
mod platform;
mod reporter;

pub use reporter::run_inventory_reporter;

use libdd_common::azure_app_services::QueryEnv;
use libdd_trace_utils::trace_utils::EnvironmentType;
use std::env;

#[derive(Clone, Copy)]
Expand All @@ -27,26 +29,19 @@ pub struct InventoryReport {
pub workload_type: &'static str,
}

/// Builds an inventory report for a supported serverless environment.
///
/// Returns `None` when the environment is unsupported or its required cloud
/// identity is unavailable. The async API leaves room for platforms such as
/// GCP that may need metadata-server lookups to complete their identity.
pub async fn build_inventory_report(
env_type: &EnvironmentType,
/// Builds an inventory report from the cloud identity collected at startup.
fn build_inventory_report(
platform: &platform::PlatformData,
process_id: &str,
report_reason: &str,
) -> Result<Option<InventoryReport>, serde_json::Error> {
let Some(platform) = platform::collect(env_type).await else {
return Ok(None);
};

let body = payload::build(process_id, report_reason, &platform)?;
Ok(Some(InventoryReport {
dd_site: &str,
) -> Result<InventoryReport, serde_json::Error> {
let body = payload::build(process_id, report_reason, platform, dd_site)?;
Ok(InventoryReport {
body,
resource_id: platform.resource_id,
resource_id: platform.resource_id.clone(),
workload_type: platform.workload_type,
}))
})
}

#[cfg(test)]
Expand Down
27 changes: 23 additions & 4 deletions crates/inventory/src/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,29 @@ pub(crate) fn build(
process_id: &str,
report_reason: &str,
platform: &PlatformData,
dd_site: &str,
) -> Result<Vec<u8>, serde_json::Error> {
build_with_env(
process_id,
report_reason,
platform,
dd_site,
&ProcessEnv,
option_env!("DD_SERVERLESS_COMPAT_VERSION"),
)
}

pub(crate) fn serverless_compat_binary_version() -> Option<&'static str> {
option_env!("DD_SERVERLESS_COMPAT_VERSION")
.map(str::trim)
.filter(|value| !value.is_empty())
}

fn build_with_env(
process_id: &str,
report_reason: &str,
platform: &PlatformData,
dd_site: &str,
env: &impl QueryEnv,
embedded_version: Option<&str>,
) -> Result<Vec<u8>, serde_json::Error> {
Expand Down Expand Up @@ -54,12 +63,12 @@ fn build_with_env(
metadata["serverless_compat_binary_version"] =
Value::String(compat_binary_version.to_string());
}
metadata["dd_site"] = Value::String(dd_site.to_string());

for (env_key, metadata_key) in [
("DD_ENV", "dd_env"),
("DD_SERVICE", "dd_service"),
("DD_VERSION", "dd_version"),
("DD_SITE", "dd_site"),
] {
if let Some(value) = env.get_var(env_key).filter(|value| !value.is_empty()) {
metadata[metadata_key] = Value::String(value);
Expand Down Expand Up @@ -102,7 +111,8 @@ mod tests {
"process-id",
"startup",
&azure_platform(),
&FakeEnv::default(),
"datadoghq.com",
&FakeEnv::new(&[("DD_SITE", "ignored.example")]),
Some("1.2.3"),
)
.unwrap();
Expand All @@ -118,6 +128,7 @@ mod tests {
assert_eq!(payload["agent_metadata"]["workload_type"], "azure_function");
assert_eq!(payload["agent_metadata"]["report_reason"], "startup");
assert_eq!(payload["agent_metadata"]["region"], "eastus");
assert_eq!(payload["agent_metadata"]["dd_site"], "datadoghq.com");
assert_eq!(
payload["agent_metadata"]["serverless_compat_binary_version"],
"1.2.3"
Expand All @@ -133,8 +144,15 @@ mod tests {
#[test]
fn reports_runtime_compat_and_binary_versions_separately() {
let env = FakeEnv::new(&[("DD_SERVERLESS_COMPAT_VERSION", "0.18.0")]);
let body =
build_with_env("pid", "startup", &azure_platform(), &env, Some("0.28.0")).unwrap();
let body = build_with_env(
"pid",
"startup",
&azure_platform(),
"datadoghq.com",
&env,
Some("0.28.0"),
)
.unwrap();
let payload: Value = serde_json::from_slice(&body).unwrap();

assert_eq!(
Expand All @@ -154,6 +172,7 @@ mod tests {
"pid",
"startup",
&azure_platform(),
"datadoghq.com",
&FakeEnv::default(),
None,
)
Expand Down
Loading
Loading