feat: frontend Actions Tab with structured API, assign/create/remove dialogs (Task 3.3)
- ActionsTab rewritten with master/detail layout (mirrors FiltersTab) - New AssignActionDialog and CreateActionDialog components - ActionConfig type extended with active, used_by_jails, source_file, has_local_override - New API functions: fetchActions, fetchAction, updateAction, createAction, deleteAction, assignActionToJail, removeActionFromJail - useActionConfig updated to use new structured endpoints - index.ts barrel exports updated
This commit is contained in:
@@ -7,8 +7,12 @@ import { ENDPOINTS } from "./endpoints";
|
||||
import type {
|
||||
ActionConfig,
|
||||
ActionConfigUpdate,
|
||||
ActionCreateRequest,
|
||||
ActionListResponse,
|
||||
ActionUpdateRequest,
|
||||
ActivateJailRequest,
|
||||
AddLogPathRequest,
|
||||
AssignActionRequest,
|
||||
AssignFilterRequest,
|
||||
ConfFileContent,
|
||||
ConfFileCreateRequest,
|
||||
@@ -386,6 +390,108 @@ export async function updateParsedAction(
|
||||
await put<undefined>(ENDPOINTS.configActionParsed(name), update);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Action discovery with active/inactive status (Task 3.1 / 3.2)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Fetch all actions from action.d/ with active/inactive status.
|
||||
*
|
||||
* Active actions (those referenced by running jails) are returned first,
|
||||
* followed by inactive ones. Both groups are sorted alphabetically.
|
||||
*
|
||||
* @returns ActionListResponse with all discovered actions and status.
|
||||
*/
|
||||
export async function fetchActions(): Promise<ActionListResponse> {
|
||||
return get<ActionListResponse>(ENDPOINTS.configActions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch full parsed detail for a single action.
|
||||
*
|
||||
* @param name - Action base name (e.g. "iptables" or "iptables.conf").
|
||||
* @returns ActionConfig with active, used_by_jails, source_file populated.
|
||||
*/
|
||||
export async function fetchAction(name: string): Promise<ActionConfig> {
|
||||
return get<ActionConfig>(ENDPOINTS.configAction(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an action's editable fields via the structured endpoint.
|
||||
*
|
||||
* Writes only the supplied fields to the ``.local`` override. Fields set
|
||||
* to ``null`` are cleared; omitted fields are left unchanged.
|
||||
*
|
||||
* @param name - Action base name (e.g. ``"iptables"``)
|
||||
* @param req - Partial update payload.
|
||||
*/
|
||||
export async function updateAction(
|
||||
name: string,
|
||||
req: ActionUpdateRequest
|
||||
): Promise<void> {
|
||||
await put<undefined>(ENDPOINTS.configAction(name), req);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a brand-new user-defined action in ``action.d/{name}.local``.
|
||||
*
|
||||
* @param req - Name and optional lifecycle commands.
|
||||
* @returns The newly created ActionConfig.
|
||||
*/
|
||||
export async function createAction(
|
||||
req: ActionCreateRequest
|
||||
): Promise<ActionConfig> {
|
||||
return post<ActionConfig>(ENDPOINTS.configActions, req);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an action's ``.local`` override file.
|
||||
*
|
||||
* Only custom ``.local``-only actions can be deleted. Attempting to delete an
|
||||
* action backed by a shipped ``.conf`` file returns 409.
|
||||
*
|
||||
* @param name - Action base name.
|
||||
*/
|
||||
export async function deleteAction(name: string): Promise<void> {
|
||||
await del<undefined>(ENDPOINTS.configAction(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign an action to a jail by appending it to the jail's action list.
|
||||
*
|
||||
* @param jailName - Jail name.
|
||||
* @param req - The action to assign with optional parameters.
|
||||
* @param reload - When ``true``, trigger a fail2ban reload after writing.
|
||||
*/
|
||||
export async function assignActionToJail(
|
||||
jailName: string,
|
||||
req: AssignActionRequest,
|
||||
reload = false
|
||||
): Promise<void> {
|
||||
const url = reload
|
||||
? `${ENDPOINTS.configJailAction(jailName)}?reload=true`
|
||||
: ENDPOINTS.configJailAction(jailName);
|
||||
await post<undefined>(url, req);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an action from a jail's action list.
|
||||
*
|
||||
* @param jailName - Jail name.
|
||||
* @param actionName - Action base name to remove.
|
||||
* @param reload - When ``true``, trigger a fail2ban reload after writing.
|
||||
*/
|
||||
export async function removeActionFromJail(
|
||||
jailName: string,
|
||||
actionName: string,
|
||||
reload = false
|
||||
): Promise<void> {
|
||||
const url = reload
|
||||
? `${ENDPOINTS.configJailActionName(jailName, actionName)}?reload=true`
|
||||
: ENDPOINTS.configJailActionName(jailName, actionName);
|
||||
await del<undefined>(url);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Parsed jail file config (Task 6.1 / 6.2)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user