Skip to content

Commit

Permalink
Merge branch 'master' into ci/104-spotless-gradle-precommit
Browse files Browse the repository at this point in the history
  • Loading branch information
QU3B1M committed Oct 16, 2024
2 parents 4b77d8b + 0ecde29 commit 1fde567
Show file tree
Hide file tree
Showing 12 changed files with 458 additions and 289 deletions.
64 changes: 64 additions & 0 deletions plugins/command-manager/openapi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
openapi: "3.0.3"
info:
title: Wazuh Indexer Command Manager API
version: "1.0"
servers:
- url: http://127.0.0.1:9200/_plugins/_command_manager
paths:
/commands:
post:
tags:
- "commands"
summary: Add a new command to the queue.
description: Add a new command to the queue.
requestBody:
required: true
content:
"application/json":
schema:
$ref: "#/components/schemas/Command"
responses:
"200":
description: OK

components:
schemas:
Command:
type: object
properties:
source:
type: string
example: "Engine"
user:
type: string
example: "user53"
target:
$ref: '#/components/schemas/Target'
action:
$ref: '#/components/schemas/Action'
timeout:
type: integer
example: 30
Target:
type: object
properties:
id:
type: string
example: "target4"
type:
type: string
example: "agent"
Action:
type: object
properties:
name:
type: string
example: "restart"
args:
type: array
items:
type: string
example: "/path/to/executable/arg6"
version:
type: string
example: "v4"
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
Expand All @@ -8,6 +7,10 @@
*/
package com.wazuh.commandmanager;

import com.wazuh.commandmanager.index.CommandIndex;
import com.wazuh.commandmanager.rest.RestPostCommandAction;
import com.wazuh.commandmanager.utils.httpclient.HttpRestClient;
import com.wazuh.commandmanager.utils.httpclient.HttpRestClientDemo;
import org.opensearch.client.Client;
import org.opensearch.cluster.metadata.IndexNameExpressionResolver;
import org.opensearch.cluster.node.DiscoveryNodes;
Expand Down Expand Up @@ -35,18 +38,15 @@
import java.util.List;
import java.util.function.Supplier;

import com.wazuh.commandmanager.index.CommandIndex;
import com.wazuh.commandmanager.rest.action.RestPostCommandAction;
import com.wazuh.commandmanager.utils.httpclient.HttpRestClient;
import com.wazuh.commandmanager.utils.httpclient.HttpRestClientDemo;

/**
* The Command Manager plugin exposes an HTTP API with a single endpoint to receive raw commands
* from the Wazuh Server. These commands are processed, indexed and sent back to the Server for its
* delivery to, in most cases, the Agents.
* The Command Manager plugin exposes an HTTP API with a single endpoint to
* receive raw commands from the Wazuh Server. These commands are processed,
* indexed and sent back to the Server for its delivery to, in most cases, the
* Agents.
*/
public class CommandManagerPlugin extends Plugin implements ActionPlugin {
public static final String COMMAND_MANAGER_BASE_URI = "/_plugins/_commandmanager";
public static final String COMMAND_MANAGER_BASE_URI = "/_plugins/_command_manager";
public static final String COMMANDS_URI = COMMAND_MANAGER_BASE_URI + "/commands";
public static final String COMMAND_MANAGER_INDEX_NAME = ".commands";
public static final String COMMAND_MANAGER_INDEX_TEMPLATE_NAME = "index-template-commands";

Expand All @@ -64,7 +64,8 @@ public Collection<Object> createComponents(
NodeEnvironment nodeEnvironment,
NamedWriteableRegistry namedWriteableRegistry,
IndexNameExpressionResolver indexNameExpressionResolver,
Supplier<RepositoriesService> repositoriesServiceSupplier) {
Supplier<RepositoriesService> repositoriesServiceSupplier
) {
this.commandIndex = new CommandIndex(client, clusterService, threadPool);

// HttpRestClient stuff
Expand All @@ -81,7 +82,8 @@ public List<RestHandler> getRestHandlers(
IndexScopedSettings indexScopedSettings,
SettingsFilter settingsFilter,
IndexNameExpressionResolver indexNameExpressionResolver,
Supplier<DiscoveryNodes> nodesInCluster) {
Supplier<DiscoveryNodes> nodesInCluster
) {
return Collections.singletonList(new RestPostCommandAction(this.commandIndex));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
Expand All @@ -8,6 +7,9 @@
*/
package com.wazuh.commandmanager.index;

import com.wazuh.commandmanager.CommandManagerPlugin;
import com.wazuh.commandmanager.model.Document;
import com.wazuh.commandmanager.utils.IndexTemplateUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.opensearch.action.admin.indices.template.put.PutIndexTemplateRequest;
Expand All @@ -29,14 +31,12 @@
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;

import com.wazuh.commandmanager.CommandManagerPlugin;
import com.wazuh.commandmanager.model.Document;
import com.wazuh.commandmanager.utils.IndexTemplateUtils;

/** Class to manage the Command Manager index and index template. */
/**
* Class to manage the Command Manager index and index template.
*/
public class CommandIndex implements IndexingOperationListener {

private static final Logger logger = LogManager.getLogger(CommandIndex.class);
private static final Logger log = LogManager.getLogger(CommandIndex.class);

private final Client client;
private final ClusterService clusterService;
Expand All @@ -45,9 +45,9 @@ public class CommandIndex implements IndexingOperationListener {
/**
* Default constructor
*
* @param client OpenSearch client.
* @param client OpenSearch client.
* @param clusterService OpenSearch cluster service.
* @param threadPool An OpenSearch ThreadPool.
* @param threadPool An OpenSearch ThreadPool.
*/
public CommandIndex(Client client, ClusterService clusterService, ThreadPool threadPool) {
this.client = client;
Expand All @@ -67,33 +67,32 @@ public CompletableFuture<RestStatus> asyncCreate(Document document) {
if (!indexTemplateExists(CommandManagerPlugin.COMMAND_MANAGER_INDEX_TEMPLATE_NAME)) {
putIndexTemplate(CommandManagerPlugin.COMMAND_MANAGER_INDEX_TEMPLATE_NAME);
} else {
logger.info(
log.info(
"Index template {} already exists. Skipping creation.",
CommandManagerPlugin.COMMAND_MANAGER_INDEX_TEMPLATE_NAME);
CommandManagerPlugin.COMMAND_MANAGER_INDEX_TEMPLATE_NAME
);
}

logger.debug("Indexing command {}", document);
log.info("Indexing command with id [{}]", document.getId());
try {
IndexRequest request =
new IndexRequest()
.index(CommandManagerPlugin.COMMAND_MANAGER_INDEX_NAME)
.source(
document.toXContent(
XContentFactory.jsonBuilder(), ToXContent.EMPTY_PARAMS))
.id(document.getId())
.create(true);
IndexRequest request = new IndexRequest()
.index(CommandManagerPlugin.COMMAND_MANAGER_INDEX_NAME)
.source(document.toXContent(XContentFactory.jsonBuilder(), ToXContent.EMPTY_PARAMS))
.id(document.getId())
.create(true);
executor.submit(
() -> {
try (ThreadContext.StoredContext ignored =
this.threadPool.getThreadContext().stashContext()) {
try (ThreadContext.StoredContext ignored = this.threadPool.getThreadContext().stashContext()) {
RestStatus restStatus = client.index(request).actionGet().status();
future.complete(restStatus);
} catch (Exception e) {
future.completeExceptionally(e);
}
});
}
);
} catch (IOException e) {
logger.error("Failed to index command with ID {}: {}", document.getId(), e);
log.error(
"Error indexing command with id [{}] due to {}", document.getId(), e);
}
return future;
}
Expand All @@ -105,9 +104,11 @@ public CompletableFuture<RestStatus> asyncCreate(Document document) {
* @return whether the index template exists.
*/
public boolean indexTemplateExists(String template_name) {
Map<String, IndexTemplateMetadata> templates =
this.clusterService.state().metadata().templates();
logger.debug("Existing index templates: {} ", templates);
Map<String, IndexTemplateMetadata> templates = this.clusterService
.state()
.metadata()
.templates();
log.debug("Existing index templates: {} ", templates);

return templates.containsKey(template_name);
}
Expand All @@ -123,28 +124,28 @@ public void putIndexTemplate(String templateName) {
// @throws IOException
Map<String, Object> template = IndexTemplateUtils.fromFile(templateName + ".json");

PutIndexTemplateRequest putIndexTemplateRequest =
new PutIndexTemplateRequest()
.mapping(IndexTemplateUtils.get(template, "mappings"))
.settings(IndexTemplateUtils.get(template, "settings"))
.name(templateName)
.patterns((List<String>) template.get("index_patterns"));

executor.submit(
() -> {
AcknowledgedResponse acknowledgedResponse =
this.client
.admin()
.indices()
.putTemplate(putIndexTemplateRequest)
.actionGet();
if (acknowledgedResponse.isAcknowledged()) {
logger.info("Index template created successfully: {}", templateName);
}
});
PutIndexTemplateRequest putIndexTemplateRequest = new PutIndexTemplateRequest()
.mapping(IndexTemplateUtils.get(template, "mappings"))
.settings(IndexTemplateUtils.get(template, "settings"))
.name(templateName)
.patterns((List<String>) template.get("index_patterns"));

executor.submit(() -> {
AcknowledgedResponse acknowledgedResponse = this.client
.admin()
.indices()
.putTemplate(putIndexTemplateRequest)
.actionGet();
if (acknowledgedResponse.isAcknowledged()) {
log.info(
"Index template [{}] created successfully",
templateName
);
}
});

} catch (IOException e) {
logger.error("Error reading index template from filesystem {}", templateName);
log.error("Error reading index template [{}] from filesystem", templateName);
}
}
}
Loading

0 comments on commit 1fde567

Please sign in to comment.