Files
computer-playbook/roles/web-app-stalwart/tasks/tracing.yml
kevinveenbirkenbachandClaude Opus 5.5 731f3b240d fix(web-app-stalwart): fail on a refused app password destroy and match the ban tracer by its events
Two findings of the CodeRabbit review of #869.

jmap_call.yml counted notCreated and notUpdated as a refused call, but
not notDestroyed. A destroy that Stalwart rejected therefore passed, and
the post-load flush cleared stalwart_app_password_stale while the retired
app password stayed valid. A notDestroyed entry now fails the call,
except notFound, where the password is already gone. The password keeps
its retired description, so the next deploy collects it again and
retries the destroy.

tracing.yml took any Stdout tracer with an include policy for the ban
tracer, so one that includes other events kept the role from creating
its own and bans stayed off the container output. The selector now also
requires every event of STALWART_BAN_TRACER.

Verified with the real task files, a stubbed container command and
canned JMAP responses: a forbidden destroy now ends with failed=1, while
notFound and a clean destroy pass; with an unrelated include tracer the
role makes a second JMAP call that creates the ban tracer, with a
complete one it does not. The previous files pass the forbidden destroy
and skip the creation in both tracer cases.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 21:32:42 +02:00

39 lines
1.5 KiB
YAML

---
- name: "📖 List Stalwart tracers"
include_tasks: jmap_call.yml
vars:
stalwart_jmap_body: >-
{{ {'using': ['urn:ietf:params:jmap:core', 'urn:stalwart:jmap'],
'methodCalls': [['x:Tracer/get', {'ids': none}, 'c0']]} | to_json }}
- name: "🔍 Resolve the file tracer and the ban tracer"
ansible.builtin.set_fact:
stalwart_log_tracers: >-
{{ stalwart_jmap.methodResponses[0][1].list
| selectattr('@type', 'equalto', 'Log')
| list }}
stalwart_ban_tracers: >-
{{ stalwart_jmap.methodResponses[0][1].list
| selectattr('@type', 'equalto', 'Stdout')
| selectattr('eventsPolicy', 'equalto', 'include')
| selectattr('events', 'superset', STALWART_BAN_TRACER.events | list)
| list }}
- name: "🔧 Point the file tracer at a directory that exists"
include_tasks: jmap_call.yml
vars:
stalwart_jmap_body: >-
{{ {'using': ['urn:ietf:params:jmap:core', 'urn:stalwart:jmap'],
'methodCalls': [['x:Tracer/set',
{'update': {stalwart_log_tracers[0].id: {'path': STALWART_LOG_DIR}}},
'c0']]} | to_json }}
when: stalwart_log_tracers | length > 0
- name: "📣 Print bans and failed logins on the container output"
include_tasks: jmap_call.yml
vars:
stalwart_jmap_body: >-
{{ {'using': ['urn:ietf:params:jmap:core', 'urn:stalwart:jmap'],
'methodCalls': [['x:Tracer/set', {'create': {'t': STALWART_BAN_TRACER}}, 'c0']]} | to_json }}
when: stalwart_ban_tracers | length == 0