refactor elastic api into multiple files

This commit is contained in:
Charlotte Croce 2025-04-18 13:06:09 -04:00
parent 9be68df982
commit bfabd6de2a
3 changed files with 98 additions and 85 deletions

View file

@ -12,9 +12,9 @@ const { getYamlViewBlocks } = require('../../blocks/sigma/sigma_view_yaml_block'
const { getSearchResultBlocks } = require('../../blocks/sigma/sigma_search_results_block'); const { getSearchResultBlocks } = require('../../blocks/sigma/sigma_search_results_block');
const { getConversionResultBlocks } = require('../../blocks/sigma/sigma_conversion_block'); const { getConversionResultBlocks } = require('../../blocks/sigma/sigma_conversion_block');
const { getRuleExplanationBlocks } = require('../../blocks/sigma/sigma_details_block'); const { getRuleExplanationBlocks } = require('../../blocks/sigma/sigma_details_block');
const { sendRuleToSiem } = require('../../services/elastic/elastic_api_service'); const { sendRuleToSiem } = require('../../services/elastic/elastic_send_rule_to_siem_service');
const { getSpaceSelectionBlocks } = require('../../blocks/sigma/sigma_space_selection_block');
const { getAllSpaces } = require('../../services/elastic/elastic_api_service'); const { getAllSpaces } = require('../../services/elastic/elastic_api_service');
const { getSpaceSelectionBlocks } = require('../../blocks/sigma/sigma_space_selection_block');
const { SIGMA_CLI_CONFIG, ELASTICSEARCH_CONFIG } = require('../../config/appConfig'); const { SIGMA_CLI_CONFIG, ELASTICSEARCH_CONFIG } = require('../../config/appConfig');

View file

@ -49,88 +49,6 @@ const getAllSpaces = () => {
return ELASTICSEARCH_CONFIG.spaces || []; return ELASTICSEARCH_CONFIG.spaces || [];
}; };
/**
* Send a rule to Elasticsearch SIEM in a specific space
*
* @param {Object} rulePayload - The rule payload to send to Elasticsearch
* @param {string} spaceId - The ID of the space to send the rule to
* @returns {Promise<Object>} - Object containing success status and response/error information
*/
const sendRuleToSiem = async (rulePayload, spaceId = 'default') => {
logger.info(`${FILE_NAME}: Sending rule to Elasticsearch SIEM in space: ${spaceId}`);
try {
const elasticConfig = getElasticConfig(spaceId);
const baseApiUrl = elasticConfig.apiEndpoint;
// Construct space-specific URL if needed
let apiUrl = baseApiUrl;
if (spaceId && spaceId !== 'default') {
// Insert space ID into URL: http://localhost:5601/api/detection_engine/rules
// becomes http://localhost:5601/s/space-id/api/detection_engine/rules
const urlParts = baseApiUrl.split('/api/');
apiUrl = `${urlParts[0]}/s/${spaceId}/api/${urlParts[1]}`;
}
logger.debug(`${FILE_NAME}: Using Elasticsearch API URL: ${apiUrl}`);
// Add index pattern to rule if provided by space config
if (elasticConfig.space && elasticConfig.space.indexPattern && !rulePayload.index) {
rulePayload.index = Array.isArray(elasticConfig.space.indexPattern)
? elasticConfig.space.indexPattern
: [elasticConfig.space.indexPattern];
logger.debug(`${FILE_NAME}: Adding index pattern to rule: ${JSON.stringify(rulePayload.index)}`);
}
// Send the request to Elasticsearch
const response = await axios({
method: 'post',
url: apiUrl,
headers: {
'Content-Type': 'application/json',
'kbn-xsrf': 'true'
},
auth: {
username: elasticConfig.username,
password: elasticConfig.password
},
data: rulePayload
});
// Process the response
if (response.status >= 200 && response.status < 300) {
logger.info(`${FILE_NAME}: Successfully sent rule to SIEM in space: ${spaceId}`);
return {
success: true,
status: response.status,
data: response.data,
space: elasticConfig.space
};
} else {
logger.error(`${FILE_NAME}: Error sending rule to SIEM. Status: ${response.status}, Response: ${JSON.stringify(response.data)}`);
return {
success: false,
status: response.status,
message: `Failed to add rule to SIEM in space ${spaceId}. Status: ${response.status}`,
data: response.data
};
}
} catch (error) {
logger.error(`${FILE_NAME}: API error sending rule to SIEM: ${error.message}`);
logger.debug(`${FILE_NAME}: API error details: ${error.response ? JSON.stringify(error.response.data) : 'No response data'}`);
const errorMessage = error.response && error.response.data && error.response.data.message
? error.response.data.message
: error.message;
return {
success: false,
message: errorMessage,
error: error
};
}
};
/** /**
* Make a generic request to an Elasticsearch API endpoint * Make a generic request to an Elasticsearch API endpoint
* *
@ -205,7 +123,6 @@ const makeElasticRequest = async (options) => {
}; };
module.exports = { module.exports = {
sendRuleToSiem,
makeElasticRequest, makeElasticRequest,
getElasticConfig, getElasticConfig,
getAllSpaces getAllSpaces

View file

@ -0,0 +1,96 @@
/**
* elastic_send_rule_to_siem_service.js
*
* Service for sending rules to Elasticsearch SIEM
*/
const axios = require('axios');
const logger = require('../../utils/logger');
const { getElasticConfig } = require('./elastic_api_service');
const FILE_NAME = 'elastic_send_rule_to_siem_service.js';
/**
* Send a rule to Elasticsearch SIEM in a specific space
*
* @param {Object} rulePayload - The rule payload to send to Elasticsearch
* @param {string} spaceId - The ID of the space to send the rule to
* @returns {Promise<Object>} - Object containing success status and response/error information
*/
const sendRuleToSiem = async (rulePayload, spaceId = 'default') => {
logger.info(`${FILE_NAME}: Sending rule to Elasticsearch SIEM in space: ${spaceId}`);
try {
const elasticConfig = getElasticConfig(spaceId);
const baseApiUrl = elasticConfig.apiEndpoint;
// Construct space-specific URL if needed
let apiUrl = baseApiUrl;
if (spaceId && spaceId !== 'default') {
// Insert space ID into URL: http://localhost:5601/api/detection_engine/rules
// becomes http://localhost:5601/s/space-id/api/detection_engine/rules
const urlParts = baseApiUrl.split('/api/');
apiUrl = `${urlParts[0]}/s/${spaceId}/api/${urlParts[1]}`;
}
logger.debug(`${FILE_NAME}: Using Elasticsearch API URL: ${apiUrl}`);
// Add index pattern to rule if provided by space config
if (elasticConfig.space && elasticConfig.space.indexPattern && !rulePayload.index) {
rulePayload.index = Array.isArray(elasticConfig.space.indexPattern)
? elasticConfig.space.indexPattern
: [elasticConfig.space.indexPattern];
logger.debug(`${FILE_NAME}: Adding index pattern to rule: ${JSON.stringify(rulePayload.index)}`);
}
// Send the request to Elasticsearch
const response = await axios({
method: 'post',
url: apiUrl,
headers: {
'Content-Type': 'application/json',
'kbn-xsrf': 'true'
},
auth: {
username: elasticConfig.username,
password: elasticConfig.password
},
data: rulePayload
});
// Process the response
if (response.status >= 200 && response.status < 300) {
logger.info(`${FILE_NAME}: Successfully sent rule to SIEM in space: ${spaceId}`);
return {
success: true,
status: response.status,
data: response.data,
space: elasticConfig.space
};
} else {
logger.error(`${FILE_NAME}: Error sending rule to SIEM. Status: ${response.status}, Response: ${JSON.stringify(response.data)}`);
return {
success: false,
status: response.status,
message: `Failed to add rule to SIEM in space ${spaceId}. Status: ${response.status}`,
data: response.data
};
}
} catch (error) {
logger.error(`${FILE_NAME}: API error sending rule to SIEM: ${error.message}`);
logger.debug(`${FILE_NAME}: API error details: ${error.response ? JSON.stringify(error.response.data) : 'No response data'}`);
const errorMessage = error.response && error.response.data && error.response.data.message
? error.response.data.message
: error.message;
return {
success: false,
message: errorMessage,
error: error
};
}
};
module.exports = {
sendRuleToSiem
};