diff --git a/services/security-dashboard.sh b/services/security-dashboard.sh index 186219d..0438726 100644 --- a/services/security-dashboard.sh +++ b/services/security-dashboard.sh @@ -458,15 +458,20 @@ _secdash_write_sudoers() { # `docker exec -i tee ` instead of a direct # host-side file write (see _secdash_grant_asterisk_access's comment on # why), plus the two Asterisk CLI calls needed after a change and the - # live registration-status check. All six are exact commands, no + # live registration-status check. All seven are exact commands, no # wildcards, scoped to the one container actually installed on this box. + # The last line (docker restart) backs the PSTN Trunk tab's "Commit + # Changes" button — see restart_asterisk_container()'s comment for why + # that exists (AST_CONFIG() live-reads not always picking up dashboard + # edits without a full container restart). if [ -n "$_ea_container" ]; then _ea_lines="$_svc_user ALL=(root) NOPASSWD: /usr/bin/docker exec -i $_ea_container tee /etc/asterisk/pjsip.conf $_svc_user ALL=(root) NOPASSWD: /usr/bin/docker exec -i $_ea_container tee /etc/easy-asterisk/categories.conf $_svc_user ALL=(root) NOPASSWD: /usr/bin/docker exec -i $_ea_container tee /etc/easy-asterisk/rooms.conf $_svc_user ALL=(root) NOPASSWD: /usr/bin/docker exec $_ea_container asterisk -rx module\ reload\ res_pjsip.so $_svc_user ALL=(root) NOPASSWD: /usr/bin/docker exec $_ea_container asterisk -rx pjsip\ show\ endpoints -$_svc_user ALL=(root) NOPASSWD: /usr/bin/docker exec $_ea_container /usr/local/bin/easy-asterisk --rebuild-dialplan" +$_svc_user ALL=(root) NOPASSWD: /usr/bin/docker exec $_ea_container /usr/local/bin/easy-asterisk --rebuild-dialplan +$_svc_user ALL=(root) NOPASSWD: /usr/bin/docker restart $_ea_container" fi cat > /etc/sudoers.d/security-dashboard << SUDOERS $_svc_user ALL=(root) NOPASSWD: /usr/bin/cscli decisions delete --id [0-9]* @@ -1644,6 +1649,27 @@ def ea_rebuild_dialplan(): run_sudo(["docker", "exec", ASTERISK_EA_CONTAINER, "/usr/local/bin/easy-asterisk", "--rebuild-dialplan"]) +def restart_asterisk_container(): + """Restarts the Easy Asterisk container - the "Commit Changes" button on + the PSTN Trunk tab. Confirmed live: dashboard writes to + pstn-permissions.conf/pstn-groups.conf/pstn-personal-dids.conf land on + disk immediately (readable via a plain `cat` right after saving), but + AST_CONFIG() in the dialplan sometimes kept returning a stale value + until the container was fully restarted - not just a `dialplan reload` + or `module reload`, an actual container restart. Root cause not fully + understood (contradicts AST_CONFIG's whole "reads fresh every call, no + restart needed" design premise, which this codebase otherwise relies on + throughout), but the restart reliably clears it, so this button exists + instead of requiring every admin to rediscover "just restart it" the + hard way. Uses the same ASTERISK_EA_CONTAINER/run_sudo mechanism as the + Easy Asterisk Admin tab's own docker exec calls - no new sudoers scope + needed beyond the one line added for this.""" + if not ASTERISK_EA_CONTAINER: + return False, "No Asterisk container detected on this box" + ok, _out, err = run_sudo(["docker", "restart", ASTERISK_EA_CONTAINER], timeout=30) + return ok, ("" if ok else (err or "Restart failed")) + + def ea_get_status(): """Registered/unregistered per extension — same 'pjsip show endpoints' parsing as the vendored get_registered_endpoints().""" @@ -2311,9 +2337,17 @@ INDEX_HTML = """