glpi: ticket-create.sh should support setting a requester (-r flag) #880

Open
opened 2026-07-23 18:37:07 +00:00 by jason.woltje · 1 comment
Owner

Summary

tools/glpi/ticket-create.sh cannot set a requester on a new GLPI ticket. Tickets are
created with the API user as the only actor and no requester (Ticket_User type: 1) attached.
For any helpdesk workflow this is a data-quality gap — a ticket with no requester loses the "who
is this for" that reporting, SLAs, and notifications depend on, and it has to be fixed by hand
after the fact.

Proposed change

Add a -r <requester> option to tools/glpi/ticket-create.sh that attaches a requester at
creation time:

  • Accepts a numeric users_id, an exact login (.name), or an unambiguous name
    (case-insensitive match across login / realname / firstname combinations).
  • Refuses ambiguous matches — if a name matches more than one user, print the candidates
    (id | login | realname firstname) and exit non-zero rather than guess. This is the key safety
    property: the wrong person must never be silently attached to a ticket.
  • Resolves before creating the ticket, so an unresolvable/ambiguous requester fails fast and
    never leaves an orphan ticket behind.
  • After successful ticket creation, POSTs Ticket_User {input:{tickets_id, users_id, type:1}}.
    A failed attach warns (with the HTTP code) but does not fail the run — the ticket already exists.
  • Prints a warning when -r is omitted so requester-less tickets are visible, not silent.
  • -f json output gains a requester_status field.

Name→ID resolution reuses the existing /User?range=0-N query pattern already used by
tools/glpi/user-list.sh (note: that endpoint returns 206 Partial Content).

Why upstream

This is an operator-agnostic capability every GLPI-using deployment benefits from; the current
lack of it forces each operator to patch the framework tool locally, and those patches are wiped
on every mosaic upgrade. A reference implementation has been written and validated against a live
GLPI instance (four distinct requesters each resolved to exactly one user; ambiguous input
correctly rejected).

Acceptance criteria

  • ticket-create.sh -r <numeric id> attaches that user as requester (type: 1).
  • ticket-create.sh -r <exact login> resolves and attaches.
  • ticket-create.sh -r "<unambiguous name>" resolves and attaches.
  • An ambiguous name prints candidates and exits non-zero without creating a ticket.
  • An unresolvable requester exits non-zero without creating a ticket.
  • Omitting -r prints a warning but still creates the ticket (back-compat).
  • -h help and usage text document -r.
  • -f json includes requester_status.

Notes

type legend for Ticket_User: 1=requester, 2=assigned/tech, 3=watcher. A future
follow-up could extend the same resolution to -a/assigned and -w/watcher, but requester is the
priority gap.

## Summary `tools/glpi/ticket-create.sh` cannot set a **requester** on a new GLPI ticket. Tickets are created with the API user as the only actor and no requester (`Ticket_User` `type: 1`) attached. For any helpdesk workflow this is a data-quality gap — a ticket with no requester loses the "who is this for" that reporting, SLAs, and notifications depend on, and it has to be fixed by hand after the fact. ## Proposed change Add a `-r <requester>` option to `tools/glpi/ticket-create.sh` that attaches a requester at creation time: - Accepts a **numeric `users_id`**, an **exact login** (`.name`), or an **unambiguous name** (case-insensitive match across login / `realname` / `firstname` combinations). - **Refuses ambiguous matches** — if a name matches more than one user, print the candidates (`id | login | realname firstname`) and exit non-zero rather than guess. This is the key safety property: the wrong person must never be silently attached to a ticket. - **Resolves before creating** the ticket, so an unresolvable/ambiguous requester fails fast and never leaves an orphan ticket behind. - After successful ticket creation, POSTs `Ticket_User` `{input:{tickets_id, users_id, type:1}}`. A failed attach warns (with the HTTP code) but does not fail the run — the ticket already exists. - Prints a **warning when `-r` is omitted** so requester-less tickets are visible, not silent. - `-f json` output gains a `requester_status` field. Name→ID resolution reuses the existing `/User?range=0-N` query pattern already used by `tools/glpi/user-list.sh` (note: that endpoint returns `206 Partial Content`). ## Why upstream This is an operator-agnostic capability every GLPI-using deployment benefits from; the current lack of it forces each operator to patch the framework tool locally, and those patches are wiped on every `mosaic` upgrade. A reference implementation has been written and validated against a live GLPI instance (four distinct requesters each resolved to exactly one user; ambiguous input correctly rejected). ## Acceptance criteria - [ ] `ticket-create.sh -r <numeric id>` attaches that user as requester (`type: 1`). - [ ] `ticket-create.sh -r <exact login>` resolves and attaches. - [ ] `ticket-create.sh -r "<unambiguous name>"` resolves and attaches. - [ ] An ambiguous name prints candidates and exits non-zero **without** creating a ticket. - [ ] An unresolvable requester exits non-zero **without** creating a ticket. - [ ] Omitting `-r` prints a warning but still creates the ticket (back-compat). - [ ] `-h` help and usage text document `-r`. - [ ] `-f json` includes `requester_status`. ## Notes `type` legend for `Ticket_User`: `1`=requester, `2`=assigned/tech, `3`=watcher. A future follow-up could extend the same resolution to `-a`/assigned and `-w`/watcher, but requester is the priority gap.
Author
Owner

Still biting — fresh occurrence 2026-07-27

Hit this again in a live helpdesk session. Confirming the issue is current against tools/glpi/ticket-create.sh as shipped: getopts "t:c:p:y:f:h" has no r, so -r 57 aborts with illegal option -- r before anything is created.

Verified the resulting data gap first-hand. A ticket created without -r came back with only:

[{"users_id":7,"type":2}]

— the API user attached as assignee, and no requester at all. The manual repair in the issue body works as described:

POST /Ticket_User  {"input":{"tickets_id":<id>,"users_id":<id>,"type":1}}

HTTP 201, readback [{"users_id":7,"type":2},{"users_id":57,"type":1}].

One angle not yet captured here: doc/tool drift

The missing flag isn't only a capability gap — it's now an active correctness trap. Downstream skills that wrap this tool already document -r as mandatory ("every ticket has a requester; ambiguous names are refused, never guessed") and instruct agents to pass it. Agents follow that instruction, hit illegal option -- r, and have to improvise the two-step workaround mid-task. So the current state is worse than a plain missing feature: the documented interface and the shipped interface disagree, and the divergence only surfaces at runtime.

That argues for landing the -r implementation rather than relaxing the docs, since the documented behaviour is the correct one. Worth adding to the acceptance criteria that -h output and the shipped usage string stay in sync with whatever the flag ends up being, so this class of drift is caught by test-help-exit-code.sh-style checks rather than by an agent failing in production.

No changes to the proposal itself — the spec in the issue body still matches what's needed.

### Still biting — fresh occurrence 2026-07-27 Hit this again in a live helpdesk session. Confirming the issue is current against `tools/glpi/ticket-create.sh` as shipped: `getopts "t:c:p:y:f:h"` has no `r`, so `-r 57` aborts with `illegal option -- r` before anything is created. Verified the resulting data gap first-hand. A ticket created without `-r` came back with only: ```json [{"users_id":7,"type":2}] ``` — the API user attached as **assignee**, and **no requester at all**. The manual repair in the issue body works as described: ``` POST /Ticket_User {"input":{"tickets_id":<id>,"users_id":<id>,"type":1}} ``` → `HTTP 201`, readback `[{"users_id":7,"type":2},{"users_id":57,"type":1}]`. ### One angle not yet captured here: doc/tool drift The missing flag isn't only a capability gap — it's now an active correctness trap. Downstream skills that wrap this tool already document `-r` as **mandatory** ("every ticket has a requester; ambiguous names are refused, never guessed") and instruct agents to pass it. Agents follow that instruction, hit `illegal option -- r`, and have to improvise the two-step workaround mid-task. So the current state is worse than a plain missing feature: the documented interface and the shipped interface disagree, and the divergence only surfaces at runtime. That argues for landing the `-r` implementation rather than relaxing the docs, since the documented behaviour is the correct one. Worth adding to the acceptance criteria that `-h` output and the shipped usage string stay in sync with whatever the flag ends up being, so this class of drift is caught by `test-help-exit-code.sh`-style checks rather than by an agent failing in production. No changes to the proposal itself — the spec in the issue body still matches what's needed.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#880