fix(crowdsec-dashboard): Show CAPI blocklist decisions in stats
The dashboard was showing 0 decisions because `cscli decisions list` only returns local decisions, not CAPI blocklist entries. Fixed by: - Parsing CAPI decision counts from `cscli metrics` output - Added separate local_decisions and capi_decisions fields - Updated overview to show "CAPI Blocklist" and "Local Bans" separately - Fixed get_capi_metrics to use metrics parsing instead of decisions list This correctly shows ~15,000 CAPI blocklist IPs instead of 0. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
32d737483b
commit
40195b5983
@ -91,11 +91,14 @@ return view.extend({
|
||||
},
|
||||
|
||||
renderStats: function(d) {
|
||||
var totalBans = (d.total_decisions || 0) + (d.capi_decisions || 0) + (d.local_decisions || 0);
|
||||
// Use total_decisions if set, otherwise sum capi + local
|
||||
if (d.total_decisions > 0) totalBans = d.total_decisions;
|
||||
var stats = [
|
||||
{ label: 'Active Bans', value: d.total_decisions || 0, type: (d.total_decisions || 0) > 0 ? 'danger' : '' },
|
||||
{ label: 'CAPI Blocklist', value: d.capi_decisions || 0, type: (d.capi_decisions || 0) > 0 ? 'success' : '' },
|
||||
{ label: 'Local Bans', value: d.local_decisions || 0, type: (d.local_decisions || 0) > 0 ? 'danger' : '' },
|
||||
{ label: 'Alerts (24h)', value: d.alerts_24h || 0, type: (d.alerts_24h || 0) > 10 ? 'warning' : '' },
|
||||
{ label: 'Scenarios', value: d.scenario_count || 0, type: 'success' },
|
||||
{ label: 'Parsers', value: d.parser_count || 0, type: '' },
|
||||
{ label: 'Bouncers', value: d.bouncer_count || 0, type: (d.bouncer_count || 0) > 0 ? 'success' : 'warning' },
|
||||
{ label: 'Countries', value: Object.keys(d.countries || {}).length, type: '' }
|
||||
];
|
||||
|
||||
@ -265,17 +265,21 @@ get_dashboard_stats() {
|
||||
check_cscli
|
||||
|
||||
json_init
|
||||
|
||||
# Count decisions
|
||||
local decisions_count
|
||||
decisions_count=$(run_cscli decisions list -o json 2>/dev/null | jsonfilter -e '@[*]' 2>/dev/null | wc -l)
|
||||
|
||||
# Count decisions - local + CAPI
|
||||
local local_decisions capi_decisions decisions_count
|
||||
local_decisions=$(run_cscli decisions list --no-api -o json 2>/dev/null | jsonfilter -e '@[*]' 2>/dev/null | wc -l)
|
||||
capi_decisions=$(run_cscli metrics 2>/dev/null | grep 'CAPI.*ban' | awk -F'|' '{sum += $5} END {print sum+0}')
|
||||
decisions_count=$((local_decisions + capi_decisions))
|
||||
json_add_int "total_decisions" "${decisions_count:-0}"
|
||||
|
||||
json_add_int "local_decisions" "${local_decisions:-0}"
|
||||
json_add_int "capi_decisions" "${capi_decisions:-0}"
|
||||
|
||||
# Count alerts (last 24h)
|
||||
local alerts_count
|
||||
alerts_count=$(run_cscli alerts list -o json --since 24h 2>/dev/null | jsonfilter -e '@[*]' 2>/dev/null | wc -l)
|
||||
json_add_int "alerts_24h" "${alerts_count:-0}"
|
||||
|
||||
|
||||
# Count bouncers
|
||||
local bouncers_count
|
||||
bouncers_count=$(run_cscli bouncers list -o json 2>/dev/null | jsonfilter -e '@[*]' 2>/dev/null | wc -l)
|
||||
@ -1893,17 +1897,22 @@ get_health_check() {
|
||||
fi
|
||||
json_add_int "bouncer_count" "${bouncer_count:-0}"
|
||||
|
||||
# Total decisions count
|
||||
local decisions_count=0
|
||||
# Total decisions count (local + CAPI from metrics)
|
||||
local local_decisions=0 capi_decisions=0 decisions_count=0
|
||||
if [ -x "$CSCLI" ]; then
|
||||
decisions_count=$(run_cscli decisions list -o json 2>/dev/null | jsonfilter -e '@[*].decisions[*]' 2>/dev/null | wc -l)
|
||||
local_decisions=$(run_cscli decisions list --no-api -o json 2>/dev/null | jsonfilter -e '@[*]' 2>/dev/null | wc -l)
|
||||
capi_decisions=$(run_cscli metrics 2>/dev/null | grep 'CAPI.*ban' | awk -F'|' '{sum += $5} END {print sum+0}')
|
||||
decisions_count=$((local_decisions + capi_decisions))
|
||||
fi
|
||||
json_add_int "decisions_count" "${decisions_count:-0}"
|
||||
json_add_int "local_decisions" "${local_decisions:-0}"
|
||||
json_add_int "capi_decisions" "${capi_decisions:-0}"
|
||||
|
||||
json_dump
|
||||
}
|
||||
|
||||
# Get CAPI blocklist metrics (decisions by origin and reason)
|
||||
# Parses from cscli metrics output since decisions list doesn't show CAPI decisions
|
||||
get_capi_metrics() {
|
||||
json_init
|
||||
|
||||
@ -1914,59 +1923,37 @@ get_capi_metrics() {
|
||||
return
|
||||
fi
|
||||
|
||||
# Get all decisions
|
||||
local decisions_output=""
|
||||
decisions_output=$(run_cscli decisions list -o json 2>/dev/null)
|
||||
|
||||
if [ -z "$decisions_output" ] || [ "$decisions_output" = "null" ]; then
|
||||
json_add_boolean "available" 1
|
||||
json_add_int "total_capi" 0
|
||||
json_add_int "total_local" 0
|
||||
json_add_string "breakdown" "[]"
|
||||
json_dump
|
||||
return
|
||||
fi
|
||||
|
||||
json_add_boolean "available" 1
|
||||
|
||||
# Count by origin
|
||||
local capi_count=0
|
||||
local local_count=0
|
||||
# Get metrics output
|
||||
local metrics_output=""
|
||||
metrics_output=$(run_cscli metrics 2>/dev/null)
|
||||
|
||||
# Parse decisions and count by origin
|
||||
# The structure is: [{decisions: [...], ...}, ...]
|
||||
# We need to count decisions where origin = "CAPI" or "crowdsec"
|
||||
# Parse Local API Decisions section from metrics
|
||||
# Format: | reason | origin | action | count |
|
||||
local capi_total=0
|
||||
local local_total=0
|
||||
|
||||
# Use a temp file for aggregation
|
||||
local tmp_file="/tmp/capi_metrics.$$"
|
||||
# Extract CAPI decisions count
|
||||
capi_total=$(echo "$metrics_output" | grep 'CAPI.*ban' | awk -F'|' '{sum += $5} END {print sum+0}')
|
||||
|
||||
# Extract all decisions with their origin and scenario
|
||||
echo "$decisions_output" | jsonfilter -e '@[*].decisions[*]' 2>/dev/null | while read -r decision; do
|
||||
local origin=$(echo "$decisions_output" | jsonfilter -e '@[*].decisions[*].origin' 2>/dev/null | head -1)
|
||||
local scenario=$(echo "$decisions_output" | jsonfilter -e '@[*].scenario' 2>/dev/null | head -1)
|
||||
echo "$origin|$scenario"
|
||||
done > "$tmp_file" 2>/dev/null
|
||||
# Extract local decisions count (origin = crowdsec or cscli)
|
||||
local_total=$(echo "$metrics_output" | grep -E '(crowdsec|cscli).*ban' | awk -F'|' '{sum += $5} END {print sum+0}')
|
||||
|
||||
# Count CAPI decisions by scenario using awk
|
||||
capi_count=$(echo "$decisions_output" | grep -o '"origin":"CAPI"' 2>/dev/null | wc -l)
|
||||
local_count=$(echo "$decisions_output" | grep -o '"origin":"crowdsec"' 2>/dev/null | wc -l)
|
||||
json_add_int "total_capi" "${capi_total:-0}"
|
||||
json_add_int "total_local" "${local_total:-0}"
|
||||
|
||||
json_add_int "total_capi" "${capi_count:-0}"
|
||||
json_add_int "total_local" "${local_count:-0}"
|
||||
|
||||
# Build breakdown by scenario for CAPI decisions
|
||||
# Parse the JSON more carefully
|
||||
# Build breakdown by scenario from metrics - parse lines with ban action
|
||||
json_add_array "breakdown"
|
||||
|
||||
# Extract unique scenarios and their counts from CAPI decisions
|
||||
local scenarios=""
|
||||
scenarios=$(echo "$decisions_output" | grep -oE '"scenario":"[^"]*"' | sort | uniq -c | sort -rn | head -10)
|
||||
|
||||
echo "$scenarios" | while read -r count scenario; do
|
||||
if [ -n "$count" ] && [ -n "$scenario" ]; then
|
||||
local name=$(echo "$scenario" | sed 's/"scenario":"//; s/"$//')
|
||||
echo "$metrics_output" | grep '|.*ban.*|' | grep -v "Action" | while IFS='|' read -r _ reason origin action count _; do
|
||||
reason=$(echo "$reason" | xargs)
|
||||
origin=$(echo "$origin" | xargs)
|
||||
count=$(echo "$count" | xargs)
|
||||
if [ -n "$reason" ] && [ -n "$count" ] && [ "$count" != "Count" ]; then
|
||||
json_add_object ""
|
||||
json_add_string "scenario" "$name"
|
||||
json_add_string "scenario" "$reason"
|
||||
json_add_string "origin" "$origin"
|
||||
json_add_int "count" "$count"
|
||||
json_close_object
|
||||
fi
|
||||
@ -1974,8 +1961,6 @@ get_capi_metrics() {
|
||||
|
||||
json_close_array
|
||||
|
||||
rm -f "$tmp_file" 2>/dev/null
|
||||
|
||||
json_dump
|
||||
}
|
||||
|
||||
@ -2184,16 +2169,28 @@ get_overview() {
|
||||
|
||||
# Quick stats
|
||||
local decisions_count=0
|
||||
local local_decisions=0
|
||||
local capi_decisions=0
|
||||
local alerts_count=0
|
||||
local bouncers_count=0
|
||||
|
||||
if [ "$cs_running" = "1" ] && [ -x "$CSCLI" ]; then
|
||||
decisions_count=$(run_cscli decisions list -o json 2>/dev/null | jsonfilter -e '@[*]' 2>/dev/null | wc -l)
|
||||
# Local decisions (from local scenarios)
|
||||
local_decisions=$(run_cscli decisions list --no-api -o json 2>/dev/null | jsonfilter -e '@[*]' 2>/dev/null | wc -l)
|
||||
|
||||
# CAPI decisions (blocklists) - parse from metrics output
|
||||
capi_decisions=$(run_cscli metrics 2>/dev/null | grep 'CAPI.*ban' | awk -F'|' '{sum += $5} END {print sum+0}')
|
||||
|
||||
# Total decisions
|
||||
decisions_count=$((local_decisions + capi_decisions))
|
||||
|
||||
alerts_count=$(run_cscli alerts list -o json --since 24h --limit 100 2>/dev/null | jsonfilter -e '@[*]' 2>/dev/null | wc -l)
|
||||
bouncers_count=$(run_cscli bouncers list -o json 2>/dev/null | jsonfilter -e '@[*]' 2>/dev/null | wc -l)
|
||||
fi
|
||||
|
||||
json_add_int "total_decisions" "${decisions_count:-0}"
|
||||
json_add_int "local_decisions" "${local_decisions:-0}"
|
||||
json_add_int "capi_decisions" "${capi_decisions:-0}"
|
||||
json_add_int "alerts_24h" "${alerts_count:-0}"
|
||||
json_add_int "bouncers" "${bouncers_count:-0}"
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user