#!/bin/sh
# Клиент JSON-RPC API Center (V4). Нужны curl и jq на рабочей машине.
# Учётка: файл с двумя строками "login" и "password" (права 0600), путь в VAPI_CRED.
#   VAPI_URL=https://<MGMT> VAPI_CRED=~/center.cred sh vapi.sh <метод> '<json params>'
# Пример: sh vapi.sh vm-list '{}' | jq '.result.data | length'
#         sh vapi.sh vms-stop '{"id":1001,"hard_timeout":90}'
#         sh vapi.sh vms-start '{"id":1001,"node_id":2}'
#         sh vapi.sh wait 1001 1 [300]   — ждать oper_status=1 (3 = Started) и снятия блокировки, до 300 с
# Код возврата: 0 — result.code=1; 1 — ответ с ошибкой (печатается); 2 — вход/транспорт.
set -eu
: "${VAPI_URL:?VAPI_URL=https://<адрес mgmtVM>}"; : "${VAPI_CRED:?VAPI_CRED=<файл с логином и паролем>}"
umask 077
M=$1; P=${2:-'{}'}
if [ "$M" = wait ]; then
  ID=$2; WANT=$3; LIM=${4:-300}; t=0
  while [ $t -lt $LIM ]; do
    R=$(sh "$0" vm-get "{\"id\":$ID}" 2>/dev/null) || true
    if printf '%s' "$R" | jq -e --argjson w "$WANT" '.result.data | (.oper_status == $w) and ((.locked // 0) == 0)' >/dev/null 2>&1; then
      printf '%s' "$R" | jq -c '.result.data | {id,node,rstart,oper_status,locked}'; exit 0; fi
    sleep 5; t=$((t+5))
  done
  echo "timeout: ВМ $ID не пришла в состояние $WANT за $LIM с" >&2; exit 1
fi
printf '%s' "$P" | jq -e . >/dev/null 2>&1 || { echo "параметры не JSON: $P" >&2; exit 2; }
U=$(sed -n 1p "$VAPI_CRED"); W=$(sed -n 2p "$VAPI_CRED")
uuid() {
  if command -v uuidgen >/dev/null 2>&1; then uuidgen | tr 'A-Z' 'a-z'
  elif [ -r /proc/sys/kernel/random/uuid ]; then cat /proc/sys/kernel/random/uuid
  else python3 -c 'import uuid; print(uuid.uuid4())'; fi
}
C=$(jq -nc --arg i "$(uuid)" --arg u "$U" --arg p "$W" '{jsonrpc:"2.0",id:$i,method:"auth3",params:{username:$u,password:$p}}' \
  | curl -sk --max-time 60 -H 'Content-Type: application/json' --data-binary @- "$VAPI_URL/.api/V4/.login/" \
  | jq -r '.result.data.cookie.APIEndpoint00 // empty')
[ -n "$C" ] || { echo "login failed" >&2; exit 2; }
jq -nc --arg i "$(uuid)" --arg m "$M" --argjson p "$P" '{jsonrpc:"2.0",id:$i,method:$m,params:$p}' \
  | curl -sk --fail-with-body --max-time 600 -H 'Content-Type: application/json' -H "X-Session-Auth: APIEndpoint00=$C" -H "Cookie: APIEndpoint00=$C" \
      --data-binary @- "$VAPI_URL/.api/V4/.req/" > "${TMPDIR:-/tmp}/vapi.$$" || { cat "${TMPDIR:-/tmp}/vapi.$$" >&2; rm -f "${TMPDIR:-/tmp}/vapi.$$"; echo "HTTP/транспорт: ошибка" >&2; exit 2; }
cat "${TMPDIR:-/tmp}/vapi.$$"; echo
jq -e '.result.code == 1' "${TMPDIR:-/tmp}/vapi.$$" >/dev/null 2>&1 || { rm -f "${TMPDIR:-/tmp}/vapi.$$"; exit 1; }
rm -f "${TMPDIR:-/tmp}/vapi.$$"
