feat: show log indices on OpenSearch admin page
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 54s
CI / docker (push) Successful in 47s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 35s

Add prefix query parameter to /admin/opensearch/indices endpoint so
the UI can fetch execution and log indices separately. OpenSearch admin
page now shows two card sections: Execution Indices and Log Indices,
each with doc count and size summary. Page restyled with CSS module
replacing inline styles. Delete endpoint also allows log index deletion.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-03-26 16:47:44 +01:00
parent 0d94132c98
commit 25ca8d5132
4 changed files with 117 additions and 28 deletions

View File

@@ -49,12 +49,14 @@ public class OpenSearchAdminController {
private final ObjectMapper objectMapper;
private final String opensearchUrl;
private final String indexPrefix;
private final String logIndexPrefix;
public OpenSearchAdminController(OpenSearchClient client, RestClient restClient,
SearchIndexerStats indexerStats, AuditService auditService,
ObjectMapper objectMapper,
@Value("${opensearch.url:http://localhost:9200}") String opensearchUrl,
@Value("${opensearch.index-prefix:executions-}") String indexPrefix) {
@Value("${opensearch.index-prefix:executions-}") String indexPrefix,
@Value("${opensearch.log-index-prefix:logs-}") String logIndexPrefix) {
this.client = client;
this.restClient = restClient;
this.indexerStats = indexerStats;
@@ -62,6 +64,7 @@ public class OpenSearchAdminController {
this.objectMapper = objectMapper;
this.opensearchUrl = opensearchUrl;
this.indexPrefix = indexPrefix;
this.logIndexPrefix = logIndexPrefix;
}
@GetMapping("/status")
@@ -100,7 +103,8 @@ public class OpenSearchAdminController {
public ResponseEntity<IndicesPageResponse> getIndices(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "20") int size,
@RequestParam(defaultValue = "") String search) {
@RequestParam(defaultValue = "") String search,
@RequestParam(defaultValue = "executions") String prefix) {
try {
Response response = restClient.performRequest(
new Request("GET", "/_cat/indices?format=json&h=index,health,docs.count,store.size,pri,rep&bytes=b"));
@@ -109,10 +113,12 @@ public class OpenSearchAdminController {
indices = objectMapper.readTree(is);
}
String filterPrefix = "logs".equals(prefix) ? logIndexPrefix : indexPrefix;
List<IndexInfoResponse> allIndices = new ArrayList<>();
for (JsonNode idx : indices) {
String name = idx.path("index").asText("");
if (!name.startsWith(indexPrefix)) {
if (!name.startsWith(filterPrefix)) {
continue;
}
if (!search.isEmpty() && !name.contains(search)) {
@@ -152,7 +158,7 @@ public class OpenSearchAdminController {
@Operation(summary = "Delete an OpenSearch index")
public ResponseEntity<Void> deleteIndex(@PathVariable String name, HttpServletRequest request) {
try {
if (!name.startsWith(indexPrefix)) {
if (!name.startsWith(indexPrefix) && !name.startsWith(logIndexPrefix)) {
throw new ResponseStatusException(HttpStatus.FORBIDDEN, "Cannot delete index outside application scope");
}
boolean exists = client.indices().exists(r -> r.index(name)).value();