Files
skill-unifi/scripts/query.sh

108 lines
4.2 KiB
Bash

#!/usr/bin/env bash
# UniFi UDM Pro — Integration API helper.
#
# Uso:
# query.sh <path> [curl args...]
#
# El <path> puede ser:
# - Path corto: /sites → se prefija /proxy/network/integration/v1
# - Path /proxy: /proxy/network/... → se usa tal cual (sirve para Classic API)
# - URL completa: https://... → se usa tal cual
set -euo pipefail
SKILL_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
ENV_FILE="$SKILL_DIR/.env"
if [[ ! -f "$ENV_FILE" ]]; then
echo "ERROR: $ENV_FILE no existe." >&2
echo " cp $SKILL_DIR/.env.example $ENV_FILE y completá UNIFI_API_KEY." >&2
exit 1
fi
set -a
# shellcheck disable=SC1090
source "$ENV_FILE"
set +a
: "${UNIFI_HOST:?UNIFI_HOST no definido en .env}"
: "${UNIFI_API_KEY:?UNIFI_API_KEY no definido en .env}"
: "${UNIFI_SITE:?UNIFI_SITE no definido en .env (debe ser el UUID del site, no el nombre)}"
PATH_ARG="${1:-}"
shift || true
if [[ -z "$PATH_ARG" ]]; then
cat >&2 <<EOF
Uso: query.sh <path> [curl args...]
Ejemplos:
query.sh /sites
query.sh /sites/{site}/devices
query.sh /sites/{site}/clients
query.sh /sites/{site}/devices/<deviceId>/statistics/latest
El placeholder {site} se reemplaza por \$UNIFI_SITE (UUID del site, en .env).
Para Classic API usar query-classic.sh (login flow distinto).
EOF
exit 2
fi
# ──────────────────────────────────────────────────────────────────────────
# READ-ONLY GUARD — la skill es read-only por diseño. Bloqueamos cualquier
# intento de cambiar el verbo HTTP o mandar body. La protección REAL la da
# el rol "Site View Only" del admin en el UDM (que también devuelve 403);
# este guard es defensa en profundidad para fallar rápido sin salir a la red.
# ──────────────────────────────────────────────────────────────────────────
for arg in "$@"; do
case "$arg" in
-X|--request|-XPOST|-XPUT|-XDELETE|-XPATCH)
echo "ERROR: la skill 'unifi' es read-only. -X/--request bloqueado." >&2
exit 3
;;
-d|--data|--data-raw|--data-binary|--data-urlencode|-T|--upload-file)
echo "ERROR: la skill 'unifi' es read-only. -d/--data/-T bloqueado." >&2
exit 3
;;
esac
done
# ──────────────────────────────────────────────────────────────────────────
# READ-ONLY GUARD — la skill es read-only por diseño. Bloqueamos cualquier
# intento de cambiar el verbo HTTP o mandar body. La protección REAL la da
# el rol "Site View Only" del admin en el UDM (que también devuelve 403);
# este guard es defensa en profundidad para evitar errores aun antes de
# salir a la red.
# ──────────────────────────────────────────────────────────────────────────
for arg in "$@"; do
case "$arg" in
-X|--request|-XPOST|-XPUT|-XDELETE|-XPATCH)
echo "ERROR: la skill 'unifi' es read-only. -X/--request bloqueado." >&2
echo " Si REALMENTE necesitás escribir, llamá a curl directo (no via este script)" >&2
echo " y sabé lo que estás haciendo." >&2
exit 3
;;
-d|--data|--data-raw|--data-binary|--data-urlencode|-T|--upload-file)
echo "ERROR: la skill 'unifi' es read-only. -d/--data/-T bloqueado." >&2
exit 3
;;
esac
done
# Expandir el placeholder {site} con el UUID del site (Integration API usa UUID, no nombre).
PATH_ARG="${PATH_ARG//\{site\}/$UNIFI_SITE}"
if [[ "$PATH_ARG" =~ ^https?:// ]]; then
URL="$PATH_ARG"
elif [[ "$PATH_ARG" == /proxy/* || "$PATH_ARG" == /api/* ]]; then
URL="https://${UNIFI_HOST}${PATH_ARG}"
else
URL="https://${UNIFI_HOST}/proxy/network/integration/v1${PATH_ARG}"
fi
exec curl -sS -k \
-H "X-API-KEY: ${UNIFI_API_KEY}" \
-H "Accept: application/json" \
"$@" \
"$URL"