Skip to content

Commit 9e1b0fa

Browse files
committed
Update sd-bridge script to add container_name and metrics_path labels
1 parent 0388411 commit 9e1b0fa

File tree

1 file changed

+43
-58
lines changed

1 file changed

+43
-58
lines changed
Lines changed: 43 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,48 @@
11
#!/usr/bin/env bash
2-
# sd-bridge.sh
3-
# Discover Docker containers by label, pull each container's discovery JSON, merge, de-duplicate,
4-
# and write a single Prometheus file_sd JSON. Optionally serve the same JSON over HTTP.
2+
# sd-bridge.sh (simplified)
3+
# Discover Docker containers by label, pull each container's discovery JSON,
4+
# add labels, merge + de-duplicate, and write a single file_sd JSON.
55

66
set -Eeuo pipefail
77

8-
# ---------- Configuration via env vars ----------
9-
LABEL_MATCH="${LABEL_MATCH:-prom_sd=true}" # filter for worker containers
8+
# --- Config (env) ---
9+
LABEL_MATCH="${LABEL_MATCH:-framework=ctf}"
1010
DEFAULT_PATH="${DISCOVERY_PATH:-/discovery}"
1111
DEFAULT_PORT="${DISCOVERY_PORT:-6688}"
1212
DEFAULT_SCHEME="${DISCOVERY_SCHEME:-http}"
13-
PREFER_NETWORK="${NETWORK_NAME:-}" # optional Docker network to prefer for IP
14-
OUT="${OUT:-/out/merged.json}" # file_sd output
15-
SLEEP="${SLEEP:-15}" # seconds between scans
16-
REQUEST_TIMEOUT="${REQUEST_TIMEOUT:-5}" # curl timeout seconds
13+
PREFER_NETWORK="${NETWORK_NAME:-}"
14+
OUT="${OUT:-/out/merged.json}"
15+
SLEEP="${SLEEP:-15}"
16+
REQUEST_TIMEOUT="${REQUEST_TIMEOUT:-5}"
17+
REWRITE_TO_IP="${REWRITE_TO_IP:-0}" # set to 1 to replace host with container IP
1718

18-
# Optional lightweight HTTP serving of OUT for http_sd
19-
SERVE_ADDR="${SERVE_ADDR:-}" # example: ":8080" to serve /targets
20-
SERVE_PATH="${SERVE_PATH:-/targets}" # URL path
21-
22-
# ---------- Helpers ----------
19+
# --- Helpers ---
2320
log(){ printf '[sd-bridge] %s\n' "$*" >&2; }
2421
get_ip(){
25-
local cid="$1"; local net="$2"
22+
local cid="$1" net="$2"
2623
if [[ -n "$net" ]]; then
2724
docker inspect "$cid" | jq -r --arg n "$net" '.[0].NetworkSettings.Networks[$n].IPAddress // empty'
2825
else
2926
docker inspect "$cid" | jq -r '.[0].NetworkSettings.Networks | to_entries[0].value.IPAddress // empty'
3027
fi
3128
}
32-
get_label(){
33-
local cid="$1" key="$2"
34-
docker inspect "$cid" | jq -r --arg k "$key" '.[0].Config.Labels[$k] // empty'
35-
}
29+
get_label(){ docker inspect "$1" | jq -r --arg k "$2" '.[0].Config.Labels[$k] // empty'; }
30+
get_name(){ docker inspect "$1" | jq -r '.[0].Name | ltrimstr("/")'; }
3631
merge_and_dedupe(){
37-
# stdin: many JSON arrays of target groups
38-
# out: one array, grouped by identical labels with unique sorted targets
3932
jq -s '
4033
add // []
4134
| map({targets: (.targets // []), labels: (.labels // {})})
42-
| sort_by(.labels)
4335
| group_by(.labels)
4436
| map({labels: (.[0].labels), targets: ([.[].targets[]] | unique | sort)})
4537
'
4638
}
47-
atomic_write(){
48-
local path="$1"; local tmp="$1.tmp"
49-
cat > "$tmp" && mv "$tmp" "$path"
50-
}
39+
atomic_write(){ local p="$1" t="$1.tmp"; cat >"$t" && mv "$t" "$p"; }
5140

52-
# ---------- Optional HTTP server ----------
53-
serve_http(){
54-
# Serves OUT at SERVE_PATH. Requires busybox httpd or python3 in the container.
55-
if command -v busybox >/dev/null 2>&1; then
56-
log "serving http_sd at ${SERVE_ADDR}${SERVE_PATH} using busybox httpd"
57-
# Busybox serves a directory. Symlink requested path to OUT.
58-
local root; root="$(dirname "$OUT")"; mkdir -p "$root"
59-
# Keep a symlink named targets.json and rewrite on change
60-
ln -sf "$(basename "$OUT")" "$root/targets.json"
61-
exec busybox httpd -f -p "${SERVE_ADDR#:}" -h "$root"
62-
elif command -v python3 >/dev/null 2>&1; then
63-
log "serving http_sd at ${SERVE_ADDR}${SERVE_PATH} using python http.server"
64-
cd "$(dirname "$OUT")" && exec python3 -m http.server "${SERVE_ADDR#:}"
65-
else
66-
log "no http server available in image; install busybox or python3"
67-
sleep infinity
68-
fi
69-
}
70-
71-
# Ensure output dir and initial file
41+
# --- Init ---
7242
mkdir -p "$(dirname "$OUT")"
7343
echo '[]' | atomic_write "$OUT"
7444

75-
# If SERVE_ADDR is set, background a tiny polling loop that keeps a shadow file named targets.json
76-
if [[ -n "$SERVE_ADDR" ]]; then
77-
# Run server in background subshell so main loop continues to update OUT
78-
serve_http &
79-
fi
80-
81-
# ---------- Main loop ----------
45+
# --- Main loop ---
8246
while true; do
8347
mapfile -t cids < <(docker ps -q --filter "label=$LABEL_MATCH" || true)
8448
if (( ${#cids[@]} == 0 )); then
@@ -90,16 +54,38 @@ while true; do
9054
files=()
9155
for cid in "${cids[@]}"; do
9256
ip="$(get_ip "$cid" "$PREFER_NETWORK")"
93-
if [[ -z "$ip" ]]; then log "skip ${cid:0:12}: no IP"; continue; fi
57+
[[ -z "$ip" ]] && { log "skip ${cid:0:12}: no IP"; continue; }
58+
name="$(get_name "$cid")"
9459

95-
# Per container overrides via labels
96-
path="$(get_label "$cid" prom_sd_path)"; path="${path:-$DEFAULT_PATH}"
97-
port="$(get_label "$cid" prom_sd_port)"; port="${port:-$DEFAULT_PORT}"
60+
# Per-container overrides (optional)
61+
path="$(get_label "$cid" prom_sd_path)"; path="${path:-$DEFAULT_PATH}"
62+
port="$(get_label "$cid" prom_sd_port)"; port="${port:-$DEFAULT_PORT}"
9863
scheme="$(get_label "$cid" prom_sd_scheme)"; scheme="${scheme:-$DEFAULT_SCHEME}"
9964

10065
url="${scheme}://${ip}:${port}${path}"
10166
f="$(mktemp)"; files+=("$f")
10267
if curl -fsSL --max-time "$REQUEST_TIMEOUT" "$url" | jq '.' > "$f" 2>/dev/null; then
68+
# Add labels (and optionally rewrite host -> container IP)
69+
if [[ "$REWRITE_TO_IP" == "1" ]]; then
70+
jq --arg ip "$ip" --arg name "$name" '
71+
map(
72+
.targets |= map($ip + ":" + (split(":")[1])) |
73+
.labels = ((.labels // {}) + {
74+
container_name: $name,
75+
scrape_path: (.labels.__metrics_path__ // "")
76+
})
77+
)
78+
' "$f" > "$f.tmp" && mv "$f.tmp" "$f"
79+
else
80+
jq --arg name "$name" '
81+
map(
82+
.labels = ((.labels // {}) + {
83+
container_name: $name,
84+
scrape_path: (.labels.__metrics_path__ // "")
85+
})
86+
)
87+
' "$f" > "$f.tmp" && mv "$f.tmp" "$f"
88+
fi
10389
log "ok ${url}"
10490
else
10591
log "fail ${url}; using []"
@@ -116,5 +102,4 @@ while true; do
116102
fi
117103

118104
sleep "$SLEEP"
119-
120105
done

0 commit comments

Comments
 (0)