Skip to content

grafos admissions

Inspect the scheduler’s admission log. Each denial surfaces a typed RejectionReason rendered via the same human prose the dashboard shows. Use --json for byte-passthrough of the wire shape; the typed_reason snake_case label is the SIEM-grade field for jq filtering.

For the full operator runbook including the typed-reason vocabulary, common jq queries, and the wire contract for the admissions and placements JSON, see the admission and placement explanations runbook.

grafos admissions

Admission log: read `/api/v1/admissions` and render the scheduler's recent admission decisions. Each denial surfaces the slice-33 typed `RejectionReason` rendered via the slice-37 human summary so the same prose appears here as in dashboards. Use `--json` for byte-passthrough of the wire shape; the typed_reason snake_case label is the SIEM-grade field for `jq` filtering
Usage: grafos admissions [OPTIONS]
Options:
--fabric <FABRIC> Fabric address (host:port). Overrides GRAFOS_FABRIC env var [env: GRAFOS_FABRIC=]
--scheduler <SCHEDULER> Scheduler URL. Falls back to `GRAFOS_SCHEDULER`, then to the Tenura-hosted credentials when that context applies [env: GRAFOS_SCHEDULER=]
--bearer <BEARER> FabricAdmin bearer token (alternative to mTLS) [env: GRAFOS_BEARER=]
--cert <CERT> Client certificate (PEM) for mTLS [env: GRAFOS_CERT=]
--wide Show additional columns in table output
--key <KEY> Client private key (PEM) matching --cert [env: GRAFOS_KEY=]
--no-color Disable color output
--ca <CA> CA bundle (PEM) used to verify the scheduler's TLS cert [env: GRAFOS_CA=]
--pool <POOL> Pool name (default: "default") [default: default]
--limit <LIMIT> Maximum rows to render in table mode. JSON mode returns every entry the scheduler reported [default: 50]
--reason <REASON> Filter to entries whose `typed_reason` matches one of the supplied snake_case labels. Repeatable: `--reason quota_hard_limit_exceeded --reason quota_burst_exceeded` matches either. Approved entries (no typed_reason) are excluded when this flag is set. Unknown labels fail the parse with a typed error listing every valid label
--json Emit JSON. The body is byte-passthrough of the scheduler's response so existing `jq` scripts keep working unchanged
-h, --help Print help
-V, --version Print version

Typed rejection reasons

Every denial carries a stable typed_reason snake_case label that SIEM rules and dashboard panels alert off:

  • insufficient_capacity — free pool has insufficient bytes across all eligible nodes.
  • no_eligible_nodes — placement constraint matches no node.
  • quota_hard_limit_exceeded — tenant hit its hard-limit quota cap.
  • quota_burst_exceeded — tenant hit the burst cap above the soft limit.
  • quota_lease_count_exceeded — tenant lease-count cap reached.
  • quota_per_node_limit_exceeded — tenant per-node capacity cap reached.
  • tenant_not_found — tenant id not registered with the scheduler.
  • node_fenced — selected node is fenced for the requested resource type.
  • budget_exhausted — power or cost budget cap reached.
  • reservation_exhausted — reservation has insufficient remaining capacity.

A typo on --reason fails closed at parse time with a typed error listing every valid label — operators don’t silently see zero rows from a bad flag.

Common jq queries

Terminal window
# Count denials by typed reason (last 50 entries).
grafos admissions --json \
| jq -r '.[] | select(.approved == false) | .typed_reason' \
| sort | uniq -c | sort -rn
# All denials for one tenant.
grafos admissions --json \
| jq '.[] | select(.tenant_id == 42 and .approved == false)'
# Approval rate this window.
grafos admissions --json \
| jq '[.[] | select(.approved)] | length as $ok |
length as $total | "\($ok)/\($total)"'

The typed_reason field is null on approved entries by design; queries should select on .approved first.