Add Deactivate Jail button for inactive jails with local override

- Add has_local_override field to InactiveJail model
- Update _build_inactive_jail and list_inactive_jails to compute the field
- Add delete_jail_local_override() service function
- Add DELETE /api/config/jails/{name}/local router endpoint
- Surface has_local_override in frontend InactiveJail type
- Show Deactivate Jail button in JailsTab when has_local_override is true
- Add tests: TestBuildInactiveJail, TestListInactiveJails, TestDeleteJailLocalOverride
This commit is contained in:
2026-03-15 13:41:00 +01:00
parent 93dc699825
commit d4d04491d2
9 changed files with 367 additions and 77 deletions

View File

@@ -39,10 +39,8 @@ import type {
LogPreviewResponse,
MapColorThresholdsResponse,
MapColorThresholdsUpdate,
PendingRecovery,
RegexTestRequest,
RegexTestResponse,
RollbackResponse,
ServerSettingsResponse,
ServerSettingsUpdate,
JailFileConfig,
@@ -552,6 +550,18 @@ export async function deactivateJail(
);
}
/**
* Delete the ``jail.d/{name}.local`` override file for an inactive jail.
*
* Only valid when the jail is **not** currently active. Use this to clean up
* leftover ``.local`` files after a jail has been fully deactivated.
*
* @param name - The jail name.
*/
export async function deleteJailLocalOverride(name: string): Promise<void> {
await del<undefined>(ENDPOINTS.configJailLocalOverride(name));
}
// ---------------------------------------------------------------------------
// fail2ban log viewer (Task 2)
// ---------------------------------------------------------------------------
@@ -593,21 +603,3 @@ export async function validateJailConfig(
): Promise<JailValidationResult> {
return post<JailValidationResult>(ENDPOINTS.configJailValidate(name), undefined);
}
/**
* Fetch the pending crash-recovery record, if any.
*
* Returns null when fail2ban is healthy and no recovery is pending.
*/
export async function fetchPendingRecovery(): Promise<PendingRecovery | null> {
return get<PendingRecovery | null>(ENDPOINTS.configPendingRecovery);
}
/**
* Rollback a bad jail — disables it and attempts to restart fail2ban.
*
* @param name - Name of the jail to disable.
*/
export async function rollbackJail(name: string): Promise<RollbackResponse> {
return post<RollbackResponse>(ENDPOINTS.configJailRollback(name), undefined);
}