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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ yarn.lock
/.vitepress/
docs/.vitepress/dist
docs/.vitepress/cache
docs/public/adp-topology/current.json
docs/public/adp-topology/current.mmd
node_modules/
# Fuzzing artifacts and coverage
fuzz/artifacts/
Expand Down
118 changes: 118 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,70 @@ export ADP_SPDX_LICENSES_VERSION := 3.28.0

# ADP-specific settings used when running.
export ADP_STANDALONE_IPC_CERT_FILE := /tmp/adp-ipc-cert.pem
ADP_TOPOLOGY_DATA_DIR := docs/public/adp-topology
ADP_TOPOLOGY_JSON_OUTPUT := $(ADP_TOPOLOGY_DATA_DIR)/current.json
ADP_TOPOLOGY_MERMAID_OUTPUT := $(ADP_TOPOLOGY_DATA_DIR)/current.mmd
ADP_TOPOLOGY_DIFF_DIR := target/adp-topology
ADP_TOPOLOGY_DIFF_BASE_OUTPUT := $(ADP_TOPOLOGY_DIFF_DIR)/base.json
ADP_TOPOLOGY_DIFF_HEAD_OUTPUT := $(ADP_TOPOLOGY_DIFF_DIR)/head.json
ADP_TOPOLOGY_DIFF_OUTPUT := $(ADP_TOPOLOGY_DIFF_DIR)/diff.json
ADP_TOPOLOGY_FORMAT := $(or $(FORMAT),json)
ADP_TOPOLOGY_OUTPUT := $(if $(filter mermaid,$(ADP_TOPOLOGY_FORMAT)),$(or $(OUTPUT),$(ADP_TOPOLOGY_MERMAID_OUTPUT)),$(ADP_TOPOLOGY_JSON_OUTPUT))
ADP_TOPOLOGY_VIEWER_URL := http://localhost:5173/topology

ifneq ($(filter generate-adp-topology,$(MAKECMDGOALS)),)
ifeq ($(strip $(CONFIG)),)
$(error CONFIG is required. Usage: make generate-adp-topology CONFIG=./datadog.yaml [FORMAT=json|mermaid] [OUTPUT=./topology.mmd])
endif
ifneq ($(filter-out json mermaid,$(ADP_TOPOLOGY_FORMAT)),)
$(error FORMAT must be 'json' or 'mermaid')
endif
ifneq ($(strip $(OUTPUT)),)
ifneq ($(ADP_TOPOLOGY_FORMAT),mermaid)
$(error OUTPUT is only valid when FORMAT=mermaid)
endif
endif
endif

ifneq ($(filter diff-adp-topology run-adp-topology-diff-viewer,$(MAKECMDGOALS)),)
ifeq ($(strip $(BASE_CONFIG)),)
$(error BASE_CONFIG is required. Usage: make diff-adp-topology BASE_CONFIG=./base.yaml HEAD_CONFIG=./head.yaml [FORMAT=json|mermaid] [OUTPUT=./topology-diff.mmd])
endif
ifeq ($(strip $(HEAD_CONFIG)),)
$(error HEAD_CONFIG is required. Usage: make diff-adp-topology BASE_CONFIG=./base.yaml HEAD_CONFIG=./head.yaml [FORMAT=json|mermaid] [OUTPUT=./topology-diff.mmd])
endif
ifneq ($(filter-out json mermaid,$(ADP_TOPOLOGY_FORMAT)),)
$(error FORMAT must be 'json' or 'mermaid')
endif
ifneq ($(strip $(OUTPUT)),)
ifneq ($(ADP_TOPOLOGY_FORMAT),mermaid)
$(error OUTPUT is only valid when FORMAT=mermaid)
endif
endif
endif

ifneq ($(filter run-adp-topology-diff-viewer,$(MAKECMDGOALS)),)
ifneq ($(strip $(FORMAT)),)
$(error FORMAT is not valid for run-adp-topology-diff-viewer; the viewer always uses JSON snapshots)
endif
ifneq ($(strip $(OUTPUT)),)
$(error OUTPUT is not valid for run-adp-topology-diff-viewer; the viewer uses generated JSON snapshots)
endif
endif

ifneq ($(filter run-adp-topology-viewer,$(MAKECMDGOALS)),)
ifeq ($(strip $(CONFIG)),)
$(error CONFIG is required. Usage: make run-adp-topology-viewer CONFIG=./datadog.yaml)
endif
ifneq ($(strip $(FORMAT)),)
ifneq ($(FORMAT),json)
$(error FORMAT is not valid for run-adp-topology-viewer; the viewer always uses JSON)
endif
endif
ifneq ($(strip $(OUTPUT)),)
$(error OUTPUT is not valid for run-adp-topology-viewer; the viewer always uses $(ADP_TOPOLOGY_JSON_OUTPUT))
endif
endif

# macOS integration-test settings.
MACOS_TEST_AGENT_VERSION ?= 7.78.0
Expand Down Expand Up @@ -366,6 +430,60 @@ run-adp-standalone-release: ## Runs ADP locally in standalone mode (release)
DD_IPC_CERT_FILE_PATH=$(ADP_STANDALONE_IPC_CERT_FILE) \
target/release/agent-data-plane --config /tmp/adp-empty-config.yaml run

.PHONY: generate-adp-topology
generate-adp-topology: build-adp
generate-adp-topology: ## Generates ADP topology data for the docs viewer (FORMAT=json|mermaid, CONFIG=...)
@mkdir -p "$(dir $(ADP_TOPOLOGY_OUTPUT))"
@echo "[*] Generating ADP topology ($(ADP_TOPOLOGY_FORMAT)): $(ADP_TOPOLOGY_OUTPUT)"
@if [ "$(ADP_TOPOLOGY_FORMAT)" = "mermaid" ]; then \
DD_API_KEY="$${DD_API_KEY:-api-key-adp-topology-viewer}" \
target/devel/agent-data-plane --config "$(CONFIG)" debug topology --format mermaid --output "$(ADP_TOPOLOGY_OUTPUT)"; \
else \
DD_API_KEY="$${DD_API_KEY:-api-key-adp-topology-viewer}" \
target/devel/agent-data-plane --config "$(CONFIG)" debug topology --format json > "$(ADP_TOPOLOGY_OUTPUT)"; \
fi

.PHONY: diff-adp-topology
diff-adp-topology: build-adp
diff-adp-topology: ## Diffs two generated ADP topologies (BASE_CONFIG=..., HEAD_CONFIG=..., FORMAT=json|mermaid)
@mkdir -p "$(ADP_TOPOLOGY_DIFF_DIR)"
@echo "[*] Generating base ADP topology: $(ADP_TOPOLOGY_DIFF_BASE_OUTPUT)"
@DD_API_KEY="$${DD_API_KEY:-api-key-adp-topology-viewer}" \
target/devel/agent-data-plane --config "$(BASE_CONFIG)" debug topology --format json > "$(ADP_TOPOLOGY_DIFF_BASE_OUTPUT)"
@echo "[*] Generating head ADP topology: $(ADP_TOPOLOGY_DIFF_HEAD_OUTPUT)"
@DD_API_KEY="$${DD_API_KEY:-api-key-adp-topology-viewer}" \
target/devel/agent-data-plane --config "$(HEAD_CONFIG)" debug topology --format json > "$(ADP_TOPOLOGY_DIFF_HEAD_OUTPUT)"
@echo "[*] Generating ADP topology diff ($(ADP_TOPOLOGY_FORMAT))"
@if [ "$(ADP_TOPOLOGY_FORMAT)" = "mermaid" ] && [ -n "$(strip $(OUTPUT))" ]; then \
target/devel/agent-data-plane debug topology --diff-base "$(ADP_TOPOLOGY_DIFF_BASE_OUTPUT)" --diff-head "$(ADP_TOPOLOGY_DIFF_HEAD_OUTPUT)" --format mermaid --output "$(OUTPUT)"; \
else \
target/devel/agent-data-plane debug topology --diff-base "$(ADP_TOPOLOGY_DIFF_BASE_OUTPUT)" --diff-head "$(ADP_TOPOLOGY_DIFF_HEAD_OUTPUT)" --format json > "$(ADP_TOPOLOGY_DIFF_OUTPUT)"; \
fi

.PHONY: run-adp-topology-diff-viewer
run-adp-topology-diff-viewer: build-adp
run-adp-topology-diff-viewer: ## Diffs two ADP configs and opens the external topology viewer (BASE_CONFIG=..., HEAD_CONFIG=...)
@$(MAKE) --no-print-directory diff-adp-topology BASE_CONFIG="$(BASE_CONFIG)" HEAD_CONFIG="$(HEAD_CONFIG)" FORMAT=json
@echo "[*] Topology diff viewer: $(ADP_TOPOLOGY_VIEWER_URL)?base=base.json&head=head.json"
@npx --yes github:DataDog/adp-visualizer-ts --base "$(ADP_TOPOLOGY_DIFF_BASE_OUTPUT)" --head "$(ADP_TOPOLOGY_DIFF_HEAD_OUTPUT)" --diff "$(ADP_TOPOLOGY_DIFF_OUTPUT)" --saluki-root "."

.PHONY: run-adp-topology-viewer
run-adp-topology-viewer: build-adp
run-adp-topology-viewer: ## Generates ADP topology data and runs the docs viewer (CONFIG=...)
@$(MAKE) --no-print-directory generate-adp-topology CONFIG="$(CONFIG)" FORMAT=json
@echo "[*] Topology viewer: $(ADP_TOPOLOGY_VIEWER_URL)"
@npx --yes github:DataDog/adp-visualizer-ts --data "$(ADP_TOPOLOGY_JSON_OUTPUT)" --saluki-root "."

.PHONY: run-adp-viewer
run-adp-viewer: ## Shorthand for run-adp-topology-viewer (CONFIG=./your-config.yaml)
run-adp-viewer:
@$(MAKE) --no-print-directory run-adp-topology-viewer CONFIG="$(CONFIG)"

.PHONY: run-adp-diff-viewer
run-adp-diff-viewer: ## Shorthand for run-adp-topology-diff-viewer (BASE_CONFIG=./base.yaml HEAD_CONFIG=./head.yaml)
run-adp-diff-viewer:
@$(MAKE) --no-print-directory run-adp-topology-diff-viewer BASE_CONFIG="$(BASE_CONFIG)" HEAD_CONFIG="$(HEAD_CONFIG)"

##@ Kubernetes

.PHONY: k8s-create-cluster
Expand Down
30 changes: 30 additions & 0 deletions bin/agent-data-plane/src/cli/debug/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ use crate::cli::utils::DataPlaneAPIClient;
mod workload;
use self::workload::{handle_workload_command, WorkloadCommand};

mod topology;
use self::topology::{handle_topology_command, TopologyCommand};

/// General debugging commands.
#[derive(FromArgs, Debug)]
#[argh(subcommand, name = "debug")]
Expand All @@ -22,6 +25,7 @@ enum DebugSubcommand {
SetLogLevel(SetLogLevelCommand),
ResetMetricLevel(ResetMetricLevelCommand),
SetMetricLevel(SetMetricLevelCommand),
Topology(TopologyCommand),
Workload(WorkloadCommand),
}

Expand Down Expand Up @@ -63,6 +67,15 @@ pub struct SetMetricLevelCommand {

/// Entrypoint for the `debug` commands.
pub async fn handle_debug_command(bootstrap_config: &GenericConfiguration, cmd: DebugCommand) {
let cmd = match handle_debug_topology_command_if_requested(bootstrap_config, cmd).await {
Ok(Some(cmd)) => cmd,
Ok(None) => return,
Err(e) => {
error!("Failed to export topology: {:#}", e);
std::process::exit(1);
}
};

let mut api_client = match DataPlaneAPIClient::from_config(bootstrap_config) {
Ok(client) => client,
Err(e) => {
Expand All @@ -76,10 +89,27 @@ pub async fn handle_debug_command(bootstrap_config: &GenericConfiguration, cmd:
DebugSubcommand::SetLogLevel(cmd) => set_log_level(&mut api_client, cmd).await,
DebugSubcommand::ResetMetricLevel(_) => reset_metric_level(&mut api_client).await,
DebugSubcommand::SetMetricLevel(cmd) => set_metric_level(&mut api_client, cmd).await,
DebugSubcommand::Topology(_) => unreachable!("handled before creating the API client"),
DebugSubcommand::Workload(cmd) => handle_workload_command(&mut api_client, cmd).await,
}
}

/// Handles `debug topology` if the given debug command is the topology export command.
///
/// Returns `Ok(None)` when the command was handled. Returns `Ok(Some(_))` with the original command when another debug
/// subcommand should continue through the regular debug path.
pub async fn handle_debug_topology_command_if_requested(
bootstrap_config: &GenericConfiguration, cmd: DebugCommand,
) -> Result<Option<DebugCommand>, saluki_error::GenericError> {
match cmd.subcommand {
DebugSubcommand::Topology(cmd) => {
handle_topology_command(bootstrap_config, cmd).await?;
Ok(None)
}
subcommand => Ok(Some(DebugCommand { subcommand })),
}
}

/// Resets the log level to the default configuration.
async fn reset_log_level(api_client: &mut DataPlaneAPIClient) {
match api_client.reset_log_level().await {
Expand Down
Loading