Diagram Data Validation
1. Overview
D2 diagrams contain hardcoded infrastructure data (IPs, hostnames, ports). This runbook ensures diagram accuracy by validating against live systems before committing.
Problem: D2 files cannot use Antora attributes - values are baked into SVG at render time.
Solution: Validate all infrastructure data against authoritative sources before creating or updating diagrams.
3. Authoritative Sources
| Data Type | Primary Source | Command |
|---|---|---|
DNS Records |
BIND (bind-01/bind-02) |
|
Host IPs |
DNS resolution |
|
Service Ports |
Live port check |
|
Switch/WLC |
Device query |
|
ISE |
ISE API |
|
Vault |
Vault API |
|
k3s Services |
kubectl |
|
4. Phase 1: DNS Validation
5. Phase 2: Service Port Validation
5.2. 2.2 Multi-Port Check
for port in 443 8443 22 1812 1813; do
nc -zv 10.50.1.20 $port 2>&1 | grep -E "succeeded|refused"
done
6. Phase 3: API Validation
7. Phase 4: Diagram Audit
8. Phase 5: Advanced Validation Patterns
8.1. 5.1 Parallel DNS Resolution
grep -oE '10\.[0-9]+\.[0-9]+\.[0-9]+' diagram.d2 | sort -u | \
xargs -P4 -I{} sh -c 'printf "%-15s %s\n" "{}" "$(host {} 2>/dev/null | awk "{print \$NF}" | head -1)"'
8.2. 5.2 Full Infrastructure Audit (One-Liner)
dig @bind-01 inside.domusdigitalis.dev AXFR | awk '/IN\s+A\s+/ {print $1, $5}' | while read h ip; do printf "%-30s %-15s %s\n" "$h" "$ip" "$(timeout 1 nc -zv $ip 22 2>&1 | grep -oE 'succeeded|refused' || echo 'no-ssh')"; done
8.3. 5.3 Compare D2 IPs vs Live DNS
comm -23 \
<(grep -oE '10\.[0-9]+\.[0-9]+\.[0-9]+' diagram.d2 | sort -u) \
<(netapi pfsense dns list 2>/dev/null | grep -oE '10\.[0-9]+\.[0-9]+\.[0-9]+' | sort -u) \
| while read ip; do echo "WARNING: $ip in D2 but not in DNS"; done
8.4. 5.4 Validate All Diagrams in Directory
for d2 in *.d2; do
echo "=== $d2 ==="
grep -oE '10\.[0-9]+\.[0-9]+\.[0-9]+' "$d2" 2>/dev/null | sort -u | \
xargs -I{} sh -c 'h=$(host {} 2>/dev/null | awk "{print \$NF}" | head -1); [ -z "$h" ] && echo "❌ {} NO PTR" || echo "✓ {} $h"'
done
8.5. 5.5 k3s Service VIP Extraction
ssh k3s-master-01 "kubectl get svc -A -o json" | \
jq -r '.items[] | select(.status.loadBalancer.ingress) | "\(.metadata.namespace)/\(.metadata.name) \(.status.loadBalancer.ingress[0].ip) \(.spec.ports[].port)"' | \
column -t
8.6. 5.6 Port Scan with Status Matrix
HOSTS="10.50.1.20 10.50.1.21 10.50.1.60 10.50.1.130"
PORTS="22 443 8443 1514 9200"
printf "%-15s" "IP"
for p in $PORTS; do printf "%-8s" "$p"; done
echo ""
for ip in $HOSTS; do
printf "%-15s" "$ip"
for port in $PORTS; do
timeout 1 nc -z $ip $port 2>/dev/null && printf "%-8s" "✓" || printf "%-8s" "-"
done
echo ""
done
8.7. 5.7 ISE Node Validation with netapi
dsource d000 dev/network
netapi ise deployment nodes 2>/dev/null | awk '/│/ && !/─/ {gsub(/│/,""); if(NF>2) print $1, $2, $3}' | column -t
8.8. 5.8 Wazuh VIP Chain Validation
for vip in wazuh wazuh-api wazuh-indexer; do
ip=$(host $vip.inside.domusdigitalis.dev 2>/dev/null | awk '{print $NF}')
printf "%-20s %-15s " "$vip" "$ip"
if [ -n "$ip" ] && [ "$ip" != "3(NXDOMAIN)" ]; then
timeout 1 nc -z $ip 443 2>/dev/null && echo "✓ HTTPS" || echo "- no HTTPS"
else
echo "❌ NO DNS"
fi
done
9. Phase 6: Validation Script
Save as ~/.local/bin/validate-diagram:
#!/usr/bin/env bash
# Validate D2 diagram IPs against live infrastructure
set -euo pipefail
D2_FILE="${1:?Usage: validate-diagram <file.d2>}"
echo "=== Extracting IPs from $D2_FILE ==="
IPS=$(grep -oE '10\.[0-9]+\.[0-9]+\.[0-9]+' "$D2_FILE" | sort -u)
echo ""
echo "=== Validating against DNS ==="
echo "$IPS" | while read -r ip; do
printf "%-15s " "$ip"
result=$(host "$ip" 2>/dev/null | awk '{print $NF}' | head -1)
if [[ "$result" == *"NXDOMAIN"* ]] || [[ -z "$result" ]]; then
echo "❌ NO PTR RECORD"
else
echo "✓ $result"
fi
done
echo ""
echo "=== Port Checks ==="
echo "$IPS" | while read -r ip; do
printf "%-15s " "$ip"
if timeout 1 nc -z "$ip" 22 2>/dev/null; then
echo "✓ SSH open"
elif timeout 1 nc -z "$ip" 443 2>/dev/null; then
echo "✓ HTTPS open"
else
echo "⚠ No common ports responding"
fi
done
Make executable:
chmod +x ~/.local/bin/validate-diagram
Usage:
validate-diagram docs/asciidoc/modules/ROOT/images/diagrams/wazuh-monitoring-sources.d2
10. Quick Reference
| Task | Command |
|---|---|
All DNS records |
|
Forward lookup |
|
Reverse lookup |
|
Port check |
|
ISE nodes |
|
k3s services |
|
Extract D2 IPs |
|
11. Pre-Commit Checklist
Before committing any D2 diagram:
-
All IPs validated via DNS (
hostcommand) -
All ports validated via netcat (
nc -zv) -
Hostnames match BIND DNS records
-
Service names match k3s
kubectl get svcoutput -
antora.yml attributes match (for documentation consistency)
-
D2 renders without errors (
d2 --theme 200 file.d2 file.svg)