modules.views
HTML pages and JSON API endpoints – the Django view layer over modules.services.
- api_acl(request, name: str)[source]
Reads or saves a module’s structured acl: edit – used by both the matrix page’s per-row modal and module_detail’s own ACL tab.
GET follows the session’s active host, like every other module_detail-feeding endpoint (api_config, api_logs, …) – module_detail only ever shows one host at a time.
POST instead trusts an explicit “host” field in the request body, defaulting to “localhost” when absent. The matrix page aggregates every configured host on one page (see acl_matrix), so it can’t rely on “the” active host the way GET does; module_detail’s own ACL tab sends its page’s active host explicitly too, for the same reason GET can’t just be reused for POST here – a POST with no “host” must mean “localhost” even if the session happens to have switched to a remote host elsewhere, since silently consulting session state here was a real footgun during the matrix’s hub-mode work (see DEV_ACL_MATRIX.md, Work Plan item 8).
- api_acl_matrix(request)[source]
Queried by another pyobs-web-admin instance acting as a hub, to fold this installation’s own local ACL matrix into its fleet-wide view – see services.merge_acl_matrices and DEV_ACL_MATRIX.md, “Hub mode interaction”.
- api_comm_user_map(request)[source]
This instance’s own comm.user -> [{“name”, “status”}] map – queried by another pyobs-web-admin instance acting as a hub to fold this installation’s modules into its own fleet-wide Users page, mirroring api_acl_matrix’s role for the ACL matrix. Includes each module’s running status so the Users page can mark which of several modules sharing one identity is actually the one running – the exact same ambiguity DEV_EJABBERD_INTEGRATION.md’s “third bug” already had to resolve for the per-module page.
- api_create_module(request)[source]
Creates a brand-new module config – follows the session’s active host like api_config, since this always operates on one host at a time (the new_module page itself), not fleet-wide.
- api_ejabberd_status(request)[source]
This instance’s own local ejabberd snapshot – queried directly when EJABBERD_HOST == “localhost” for whichever instance is rendering the dashboard, or by another pyobs-web-admin instance acting as a hub when its own EJABBERD_HOST names this host (see DEV_EJABBERD_INTEGRATION.md, Hub-mode delegation). Always answers using this instance’s own ejabberd.py calls – like api_acl_matrix, it has no host-awareness of its own; the caller decides, via EJABBERD_HOST, that this is the right instance to ask.
- api_ejabberd_summary(request)[source]
Fleet-wide ejabberd summary for the dashboard’s tile + per-module indicator. Not host-aware via _active_host like most of this app’s other API views – ejabberd is normally one shared server for the whole fleet (see DEV_EJABBERD_INTEGRATION.md), so this answers the same regardless of which host’s dashboard is currently being viewed.
- api_ejabberd_user(request, user: str)[source]
Live ejabberd state for one JID local-part – the delegation target for whichever instance actually hosts a module’s config once it has resolved that module’s comm.user (see DEV_EJABBERD_INTEGRATION.md, Hub-mode delegation: the module’s own host and EJABBERD_HOST can be two different hosts entirely). No host-awareness here either, same reasoning as api_ejabberd_status.
- api_ejabberd_users(request)[source]
Every registered account’s live/ban/last-seen state – the delegation target for _ejabberd_all_users, mirroring api_ejabberd_status’s “no host-awareness of its own” shape. Feeds the fleet-wide Users page.
- api_ejabberd_users_kick(request, user: str)[source]
Force-disconnects one session of user (identified by its XMPP resource, supplied by the caller – the Users page already has it from the live session data it’s already displaying) without touching the account itself (still registered, same password) – distinct from ban (which also blocks new logins) and unregister (which deletes the account). Useful for a stuck/duplicate session. Uses kick_session with a fixed, greppable reason rather than kick_user’s reason-less generic disconnect, so the module side can tell an intentional admin kick apart from any other disconnect cause.
- api_module_ejabberd(request, name: str)[source]
Per-module ejabberd state for the module page’s Overview tab. Host-aware in two separate layers: which instance actually runs module name (session’s active host, like every other module_detail-feeding endpoint – proxies the whole request there if remote), and, once resolved locally, which host ejabberd itself lives on (EJABBERD_HOST, via _ejabberd_user) – these can be two different hosts entirely. A module with no comm.user answers {“comm_user”: None} without attempting any ejabberd query at all.
Also reports module_running (this module’s own process, via get_module_status) – two modules can share the same comm.user (e.g. a “_test” copy reusing a real module’s identity), so a live session for that JID doesn’t necessarily belong to this module; the caller must not present sessions/last as “this module’s connection” unless this module is actually the one running. registered/ban_details are account-level facts, not session state, so unlike sessions/last they’re queried and returned regardless of module_running – registering/resetting/banning an account for a module that isn’t running yet (or anymore) is a real, intended use case (DEV_EJABBERD_USER_MANAGEMENT.md), not something that should require starting the module first.
shared_with (DEV_EJABBERD_USER_MANAGEMENT.md) lists every other local module resolving to the same comm.user – a config fact, independent of ejabberd/running state, so it’s always included once comm_user resolves. Feeds the write actions’ confirmation UI, which must show this before a ban/unregister goes through (see that doc’s Design).
- api_module_ejabberd_change_password(request, name: str)[source]
Resets module name’s comm.user’s XMPP password to a freshly generated random value, then writes it into comm.password: for every local module sharing that identity (services.save_comm_password) – cross-host shared identities aren’t handled, matching this app’s usual “hub mode aggregates only when a feature explicitly needs it” model (see DEVELOPMENT.md’s Wide conventions).
Accepts an explicit “host” in the body, same as api_module_ejabberd_register – see _resolve_action_host.
- api_module_ejabberd_register(request, name: str)[source]
Registers module name’s comm.user as a new XMPP account, using the password its own config already declares – no password is read from the request body at all. The point is making an existing comm.user/comm.password config actually work, not choosing a fresh credential (see DEV_EJABBERD_USER_MANAGEMENT.md, Design).
Accepts an explicit “host” in the body (see _resolve_action_host) so the Users page can target a specific module regardless of the session’s active host; the module page’s own call omits it and falls back to session state as before.
- api_xmpp_users(request)[source]
Every registered ejabberd account’s live/ban/last-seen state, for the Users page. Same “fleet-shared, not host-aware via _active_host” shape as api_ejabberd_summary – delegates via _ejabberd_all_users (EJABBERD_HOST resolution), independent of which host’s Users page happened to be loaded.
- fleet_overview(request)[source]
Lightweight fleet-wide overview: one row per host (reachable or not, running/stopped/ total counts, aggregate CPU/RAM), each linking into that host’s own per-host Dashboard. Deliberately no per-module rows and no bulk (or even per-module) actions at all – see DEVELOPMENT.md’s “Two dashboards” idea for why: Start All/Stop All and per-module quick actions belong on the per-host Dashboard, since a fleet-wide “Stop All” from one button is a real footgun. Aggregates every configured hub host regardless of which host is currently “active” in the session, exactly like acl_matrix/all_logs/xmpp_users – this page’s whole point is fleet-wide visibility, not one host at a time.
- new_module(request)[source]
A dedicated page (not a modal – this app’s own established mobile-friendliness convention, see DEV_EJABBERD_USER_MANAGEMENT.md’s Users page) for the one-field “create a brand-new module config” form. Follows the session’s active host like module_detail itself, since this always operates on one host at a time, not fleet-wide.
- packages(request)[source]
Follows the session’s active host, like dashboard/module_detail – installed pyobs-* packages and their pip environment are a per-host thing, so this shows one host’s full detail (with Update buttons) at a time. See fleet_overview’s own package-version matrix for the cross-host “is everything on the same version?” view, the same Dashboard/Overview split this app already uses for modules (DEVELOPMENT.md’s “Two dashboards”).
Data itself (installed + latest PyPI versions) is loaded client-side via api_packages, since the PyPI lookups are slow enough that rendering them synchronously here would block the page load.
- xmpp_users(request)[source]
Fleet-wide XMPP account listing: every module’s comm.user, cross-referenced against every registered ejabberd account (including ones no module claims, e.g. an “admin” account used by a human, not pyobs) – aggregates every configured hub host (like acl_matrix/all_logs) for the module-ownership side, since a comm.user can be configured on any host in the fleet, all normally pointing at the same one shared ejabberd instance (see DEV_EJABBERD_INTEGRATION.md, Hub-mode delegation – ejabberd itself is queried once via api_xmpp_users, not per host).
Deliberately read-only: DEV_EJABBERD_USER_MANAGEMENT.md’s write actions (register/reset password/ban/unregister) stay on the module page that owns each identity – this page links there rather than duplicating those actions, since several of them (register’s “use the module’s own configured password”, the config write-back) are only meaningful in a module’s own context, and some registered accounts here have no owning module at all to route a write to.