diff --git a/controllers/agents.js b/controllers/agents.js index 03679c85..3ba88605 100644 --- a/controllers/agents.js +++ b/controllers/agents.js @@ -375,6 +375,46 @@ router.get('/outdated', cache(), function(req, res) { execute.exec(python_bin, [wazuh_control], data_request, function (data) { res_h.send(req, res, data); }); }) +/** + * @api {get} /purgeable/:timeframe Get list of purgeable agents + * @apiName GetAgentsPurgeable + * @apiGroup Info + * + * @apiParam {Number or [n_days]d[n_hours]h[n_minutes]m[n_seconds]s} timeframe Time from last connection. + * @apiParam {Number} [offset] First element to return in the collection. + * @apiParam {Number} [limit=500] Maximum number of elements to return. + * + * @apiDescription Returns a list of agents that can be purged + * + * @apiExample {curl} Example usage*: + * curl -u foo:bar -k -X GET "https://127.0.0.1:55000/agents/purgeable/10800?pretty" + * curl -u foo:bar -k -X GET "https://127.0.0.1:55000/agents/purgeable/3h30m?pretty" + * + */ +router.get('/purgeable/:timeframe', cache(), function(req, res) { + + logger.debug(req.connection.remoteAddress + " GET /agents/purgeable/:timeframe"); + + var data_request = {'function': '/agents/purgeable/:timeframe', 'arguments': {}}; + var filters = {'timeframe':'timeframe_type', 'offset': 'numbers', 'limit': 'numbers'}; + + if (!filter.check(req.params, filters, req, res)) // Filter with error + return; + + if ('timeframe' in req.params) + data_request['arguments']['timeframe'] = req.params.timeframe; + else + res_h.bad_request(req, res, 604, "Missing field: 'timeframe'"); + + if ('offset' in req.query) + data_request['arguments']['offset'] = req.query.offset; + + if ('limit' in req.query) + data_request['arguments']['limit'] = req.query.limit; + + execute.exec(python_bin, [wazuh_control], data_request, function (data) { res_h.send(req, res, data); }); +}) + /** * @api {get} /agents/name/:agent_name Get an agent by its name * @apiName GetAgentsName @@ -1007,5 +1047,38 @@ router.post('/insert', function(req, res) { res_h.bad_request(req, res, 604, "Missing fields. Mandatory fields: id, name, ip, key"); }) +/** + * @api {post} /agents/purge Purge old agents from manager + * @apiName PostAgentsPurge + * @apiGroup Purge + * + * @apiParam {Number or [n_days]d[n_hours]h[n_minutes]m[n_seconds]s} timeframe Time from last connection. + * @apiParam {Boolean} verbose Return information about agents purgeds. + * + * @apiDescription Deletes all agents that did not connected in the last timeframe seconds. + * + * @apiExample {curl} Example usage*: + * curl -u foo:bar -k -X POST -H "Content-Type:application/json" -d '{"timeframe":10800}' "https://127.0.0.1:55000/agents/purge?pretty" + * curl -u foo:bar -k -X POST -H "Content-Type:application/json" -d '{"timeframe":"3h30m"}' "https://127.0.0.1:55000/agents/purge?pretty" + * + */ +router.post('/purge', function(req, res) { + logger.debug(req.connection.remoteAddress + " POST /agents/purge"); + + var data_request = {'function': 'POST/agents/purge', 'arguments': {}}; + var filters = {'timeframe':'timeframe_type', 'verbose':'boolean'}; + + if (!filter.check(req.body, filters, req, res)) // Filter with error + return; + + if ('verbose' in req.body) + data_request['arguments']['verbose'] = req.body.verbose; + + if ('timeframe' in req.body){ + data_request['arguments']['timeframe'] = req.body.timeframe; + execute.exec(python_bin, [wazuh_control], data_request, function (data) { res_h.send(req, res, data); }); + }else + res_h.bad_request(req, res, 604, "Missing field: 'timeframe'"); +}) -module.exports = router; +module.exports = router; \ No newline at end of file diff --git a/helpers/errors.js b/helpers/errors.js index 7ecdaa90..9d839a30 100755 --- a/helpers/errors.js +++ b/helpers/errors.js @@ -48,6 +48,10 @@ errors['615'] = "Param not valid. Valid characters: a-z A-Z 0-9"; // keys errors['ossec_key'] = 615; errors['616'] = "Param not valid. Valid characters: array of numbers"; errors['array_numbers'] = 616; +errors['timeframe_type'] = 617; +errors['617'] = "Param not valid. Valid characters: \"[0-9]d[0-9]h[0-9]m[0-9]s\" or 0-9" +errors['boolean'] = 618; +errors['618'] = "Param not valid. Valid characters: true or false" errors['700'] = "File not found" diff --git a/helpers/input_validation.js b/helpers/input_validation.js old mode 100644 new mode 100755 index 81e30a9f..5a9cdb0e --- a/helpers/input_validation.js +++ b/helpers/input_validation.js @@ -133,6 +133,16 @@ exports.ossec_key = function(param) { return false; } +// [n_days]d[n_hours]h[n_minutes]m[n_seconds]s +exports.timeframe_type = function(param) { + if (typeof param != 'undefined'){ + var regex = /^((\d{1,}[d]){0,1}(\d{1,}[h]){0,1}(\d{1,}[m]){0,1}(\d{1,}[s]){0,1}){1}$|^\d{1,}$/; + return regex.test(param); + } + else + return false; +} + exports.boolean = function(n) { if (typeof n != 'undefined'){ var regex = /^true|false$/; @@ -141,3 +151,4 @@ exports.boolean = function(n) { else return false; } + diff --git a/models/wazuh-api.py b/models/wazuh-api.py old mode 100755 new mode 100644 index 501f7f01..dbe80ff0 --- a/models/wazuh-api.py +++ b/models/wazuh-api.py @@ -199,6 +199,8 @@ def usage(): 'PUT/agents/groups/:group_id': Agent.create_group, 'DELETE/agents/groups/:group_id':Agent.remove_group, 'DELETE/agents/:agent_id/group':Agent.unset_group, + 'POST/agents/purge': Agent.purge_agents, + '/agents/purgeable/:timeframe': Agent.get_purgeable_agents_json, '/decoders': Decoder.get_decoders, '/decoders/files': Decoder.get_decoders_files,