Add filter discovery endpoints with active/inactive status (Task 2.1)

- Add list_filters() and get_filter() to config_file_service.py:
  scans filter.d/, parses [Definition] + [Init] sections, merges .local
  overrides, and cross-references running jails to set active/used_by_jails
- Add FilterConfig.active, used_by_jails, source_file, has_local_override
  fields to the Pydantic model; add FilterListResponse and FilterNotFoundError
- Add GET /api/config/filters and GET /api/config/filters/{name} to config.py
- Remove the shadowed GET /api/config/filters list route from file_config.py;
  rename GET /api/config/filters/{name} raw variant to /filters/{name}/raw
- Update frontend: fetchFilterFiles() adapts FilterListResponse -> ConfFilesResponse;
  add fetchFilters() and fetchFilter() to api/config.ts; remove unused
  fetchFilterFiles/fetchActionFiles calls from useConfigActiveStatus
- Fix ConfigPageLogPath test mock to include fetchInactiveJails and related
  exports introduced by Stage 1
- Backend: 169 tests pass, mypy --strict clean, ruff clean
- Frontend: 63 tests pass, tsc --noEmit clean, eslint clean
This commit is contained in:
2026-03-13 16:48:27 +01:00
parent 8d9d63b866
commit 4c138424a5
14 changed files with 989 additions and 92 deletions

View File

@@ -274,6 +274,29 @@ export interface FilterConfig {
datepattern: string | null;
/** journalmatch, or null. */
journalmatch: string | null;
/**
* True when this filter is referenced by at least one currently running jail.
* Defaults to false when the status was not computed (e.g. /parsed endpoint).
*/
active: boolean;
/**
* Names of currently enabled jails that reference this filter.
* Empty when active is false.
*/
used_by_jails: string[];
/** Absolute path to the .conf source file. Empty string when not computed. */
source_file: string;
/** True when a .local override file exists alongside the base .conf. */
has_local_override: boolean;
}
/**
* Response for GET /api/config/filters.
* Lists all discovered filters with active/inactive status.
*/
export interface FilterListResponse {
filters: FilterConfig[];
total: number;
}
/**