2010-07-02 Ramon Novoa <rnovoa@artica.es>
* modules/pandora_module.h, modules/pandora_module_factory.cc, modules/pandora_module.cc, pandora_windows_service.cc: Added the module_condition feature. See http://openideas.info/wiki/ for more information. git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@2956 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
This commit is contained in:
parent
a7b62691b3
commit
e693d976b0
|
@ -1,3 +1,10 @@
|
||||||
|
2010-07-02 Ramon Novoa <rnovoa@artica.es>
|
||||||
|
|
||||||
|
* modules/pandora_module.h, modules/pandora_module_factory.cc,
|
||||||
|
modules/pandora_module.cc, pandora_windows_service.cc: Added the
|
||||||
|
module_condition feature. See http://openideas.info/wiki/ for more
|
||||||
|
information.
|
||||||
|
|
||||||
2010-06-30 Ramon Novoa <rnovoa@artica.es>
|
2010-06-30 Ramon Novoa <rnovoa@artica.es>
|
||||||
|
|
||||||
* windows/pandora_wmi.cc: getDiskFreeSpacePercent should not return
|
* windows/pandora_wmi.cc: getDiskFreeSpacePercent should not return
|
||||||
|
|
|
@ -44,6 +44,7 @@ Pandora_Module::Pandora_Module (string name) {
|
||||||
this->async = false;
|
this->async = false;
|
||||||
this->data_list = NULL;
|
this->data_list = NULL;
|
||||||
this->inventory_list = NULL;
|
this->inventory_list = NULL;
|
||||||
|
this->condition_list = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,7 +53,27 @@ Pandora_Module::Pandora_Module (string name) {
|
||||||
* Should be redefined by child classes.
|
* Should be redefined by child classes.
|
||||||
*/
|
*/
|
||||||
Pandora_Module::~Pandora_Module () {
|
Pandora_Module::~Pandora_Module () {
|
||||||
|
Condition *cond = NULL;
|
||||||
|
list<Condition *>::iterator iter;
|
||||||
|
|
||||||
|
/* Clean data lists */
|
||||||
this->cleanDataList ();
|
this->cleanDataList ();
|
||||||
|
|
||||||
|
/* Clean condition list */
|
||||||
|
if (this->condition_list != NULL && this->condition_list->size () > 0) {
|
||||||
|
iter = this->condition_list->begin ();
|
||||||
|
for (iter = this->condition_list->begin ();
|
||||||
|
iter != this->condition_list->end ();
|
||||||
|
iter++) {
|
||||||
|
/* Free regular expressions */
|
||||||
|
cond = *iter;
|
||||||
|
if (cond->string_value != "") {
|
||||||
|
regfree (&(cond->regexp));
|
||||||
|
}
|
||||||
|
delete (*iter);
|
||||||
|
}
|
||||||
|
delete (this->condition_list);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -594,3 +615,116 @@ string
|
||||||
Pandora_Module::getSave () {
|
Pandora_Module::getSave () {
|
||||||
return this->save;
|
return this->save;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new condition to the module.
|
||||||
|
*
|
||||||
|
* @param condition Condition string.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Pandora_Module::addCondition (string condition) {
|
||||||
|
Condition *cond;
|
||||||
|
char operation[255], string_value[1024], command[1024];
|
||||||
|
|
||||||
|
/* Create the condition list if it does not exist */
|
||||||
|
if (this->condition_list == NULL) {
|
||||||
|
this->condition_list = new list<Condition *> ();
|
||||||
|
if (this->condition_list == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the new condition */
|
||||||
|
cond = new Condition;
|
||||||
|
if (cond == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cond->value_1 = 0;
|
||||||
|
cond->value_2 = 0;
|
||||||
|
|
||||||
|
/* Numeric comparison */
|
||||||
|
if (sscanf (condition.c_str (), "%255s %lf %1024[^]", operation, &(cond->value_1), command) == 3) {
|
||||||
|
cond->operation = operation;
|
||||||
|
cond->command = command;
|
||||||
|
this->condition_list->push_back (cond);
|
||||||
|
/* Regular expression */
|
||||||
|
} else if (sscanf (condition.c_str (), "=~ %1024s %1024[^]", string_value, command) == 2) {
|
||||||
|
cond->operation = "=~";
|
||||||
|
cond->string_value = string_value;
|
||||||
|
cond->command = command;
|
||||||
|
if (regcomp (&(cond->regexp), string_value, 0) != 0) {
|
||||||
|
pandoraDebug ("Invalid regular expression %s", string_value);
|
||||||
|
delete (cond);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->condition_list->push_back (cond);
|
||||||
|
/* Interval */
|
||||||
|
} else if (sscanf (condition.c_str (), "(%lf , %lf) %1024[^]", &(cond->value_1), &(cond->value_2), command) == 3) {
|
||||||
|
cond->operation = "()";
|
||||||
|
cond->command = command;
|
||||||
|
this->condition_list->push_back (cond);
|
||||||
|
} else {
|
||||||
|
pandoraDebug ("Invalid module condition: %s", condition.c_str ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluates and executes module conditions.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Pandora_Module::evaluateConditions () {
|
||||||
|
unsigned char run;
|
||||||
|
double double_value;
|
||||||
|
string string_value;
|
||||||
|
Condition *cond = NULL;
|
||||||
|
list<Condition *>::iterator iter;
|
||||||
|
PROCESS_INFORMATION pi;
|
||||||
|
STARTUPINFO si;
|
||||||
|
Pandora_Data *pandora_data = NULL;
|
||||||
|
regex_t regex;
|
||||||
|
|
||||||
|
/* No data */
|
||||||
|
if ( (!this->has_output) || this->data_list == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the module data */
|
||||||
|
pandora_data = data_list->front ();
|
||||||
|
|
||||||
|
/* Get the string value of the data */
|
||||||
|
string_value = pandora_data->getValue ();
|
||||||
|
|
||||||
|
/* Get the double value of the data */
|
||||||
|
try {
|
||||||
|
double_value = Pandora_Strutils::strtodouble (string_value);
|
||||||
|
} catch (Pandora_Strutils::Invalid_Conversion e) {
|
||||||
|
double_value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->condition_list != NULL && this->condition_list->size () > 0) {
|
||||||
|
iter = this->condition_list->begin ();
|
||||||
|
for (iter = this->condition_list->begin ();
|
||||||
|
iter != this->condition_list->end ();
|
||||||
|
iter++) {
|
||||||
|
cond = *iter;
|
||||||
|
run = 0;
|
||||||
|
if ((cond->operation == ">" && double_value > cond->value_1) ||
|
||||||
|
(cond->operation == "<" && double_value < cond->value_1) ||
|
||||||
|
(cond->operation == "=" && double_value == cond->value_1) ||
|
||||||
|
(cond->operation == "!=" && double_value != cond->value_1) ||
|
||||||
|
(cond->operation == "=~" && regexec (&(cond->regexp), string_value.c_str (), 0, NULL, 0) == 0) ||
|
||||||
|
(cond->operation == "()" && double_value > cond->value_1 && double_value < cond->value_2)) {
|
||||||
|
|
||||||
|
/* Run the condition command */
|
||||||
|
ZeroMemory (&si, sizeof (si));
|
||||||
|
ZeroMemory (&pi, sizeof (pi));
|
||||||
|
if (CreateProcess (NULL , (CHAR *)cond->command.c_str (), NULL, NULL, FALSE,
|
||||||
|
CREATE_NO_WINDOW, NULL, NULL, &si, &pi) == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
WaitForSingleObject(pi.hProcess, this->module_timeout);
|
||||||
|
CloseHandle (pi.hProcess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include "../pandora.h"
|
#include "../pandora.h"
|
||||||
#include "pandora_data.h"
|
#include "pandora_data.h"
|
||||||
|
#include "boost/regex.h"
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -87,6 +88,18 @@ namespace Pandora_Modules {
|
||||||
MODULE_PLUGIN /**< Plugin */
|
MODULE_PLUGIN /**< Plugin */
|
||||||
} Module_Kind;
|
} Module_Kind;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the structure that holds module conditions.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
double value_1;
|
||||||
|
double value_2;
|
||||||
|
string string_value;
|
||||||
|
string operation;
|
||||||
|
string command;
|
||||||
|
regex_t regexp;
|
||||||
|
} Condition;
|
||||||
|
|
||||||
const string module_exec_str = "module_exec";
|
const string module_exec_str = "module_exec";
|
||||||
const string module_proc_str = "module_proc";
|
const string module_proc_str = "module_proc";
|
||||||
const string module_service_str = "module_service";
|
const string module_service_str = "module_service";
|
||||||
|
@ -140,6 +153,7 @@ namespace Pandora_Modules {
|
||||||
string module_kind_str;
|
string module_kind_str;
|
||||||
Module_Kind module_kind;
|
Module_Kind module_kind;
|
||||||
string save;
|
string save;
|
||||||
|
list<Condition *> *condition_list;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -221,6 +235,8 @@ namespace Pandora_Modules {
|
||||||
void setSave (string save);
|
void setSave (string save);
|
||||||
|
|
||||||
void exportDataOutput ();
|
void exportDataOutput ();
|
||||||
|
void addCondition (string condition);
|
||||||
|
void evaluateConditions ();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,7 @@ using namespace Pandora_Strutils;
|
||||||
#define TOKEN_REGEXP ("module_regexp ")
|
#define TOKEN_REGEXP ("module_regexp ")
|
||||||
#define TOKEN_PLUGIN ("module_plugin ")
|
#define TOKEN_PLUGIN ("module_plugin ")
|
||||||
#define TOKEN_SAVE ("module_save ")
|
#define TOKEN_SAVE ("module_save ")
|
||||||
|
#define TOKEN_CONDITION ("module_condition ")
|
||||||
|
|
||||||
string
|
string
|
||||||
parseLine (string line, string token) {
|
parseLine (string line, string token) {
|
||||||
|
@ -123,11 +124,13 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) {
|
||||||
string module_retries, module_startdelay, module_retrydelay;
|
string module_retries, module_startdelay, module_retrydelay;
|
||||||
string module_perfcounter, module_tcpcheck;
|
string module_perfcounter, module_tcpcheck;
|
||||||
string module_port, module_timeout, module_regexp;
|
string module_port, module_timeout, module_regexp;
|
||||||
string module_plugin, module_save;
|
string module_plugin, module_save, module_condition;
|
||||||
Pandora_Module *module;
|
Pandora_Module *module;
|
||||||
bool numeric;
|
bool numeric;
|
||||||
Module_Type type;
|
Module_Type type;
|
||||||
long agent_interval;
|
long agent_interval;
|
||||||
|
list<string> condition_list;
|
||||||
|
list<string>::iterator condition_iter;
|
||||||
|
|
||||||
module_name = "";
|
module_name = "";
|
||||||
module_type = "";
|
module_type = "";
|
||||||
|
@ -143,7 +146,7 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) {
|
||||||
module_logevent = "";
|
module_logevent = "";
|
||||||
module_source = "";
|
module_source = "";
|
||||||
module_eventtype = "";
|
module_eventtype = "";
|
||||||
module_eventcode = "";
|
module_eventcode = "";
|
||||||
module_pattern = "";
|
module_pattern = "";
|
||||||
module_application = "";
|
module_application = "";
|
||||||
module_async = "";
|
module_async = "";
|
||||||
|
@ -160,7 +163,8 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) {
|
||||||
module_timeout = "";
|
module_timeout = "";
|
||||||
module_regexp = "";
|
module_regexp = "";
|
||||||
module_plugin = "";
|
module_plugin = "";
|
||||||
module_save = "";
|
module_save = "";
|
||||||
|
module_condition = "";
|
||||||
|
|
||||||
stringtok (tokens, definition, "\n");
|
stringtok (tokens, definition, "\n");
|
||||||
|
|
||||||
|
@ -285,6 +289,15 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) {
|
||||||
if (module_save == "") {
|
if (module_save == "") {
|
||||||
module_save = parseLine (line, TOKEN_SAVE);
|
module_save = parseLine (line, TOKEN_SAVE);
|
||||||
}
|
}
|
||||||
|
if (module_condition == "") {
|
||||||
|
module_condition = parseLine (line, TOKEN_CONDITION);
|
||||||
|
|
||||||
|
/* Queue the condition and keep looking for more */
|
||||||
|
if (module_condition != "") {
|
||||||
|
condition_list.push_back (module_condition);
|
||||||
|
module_condition = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
iter++;
|
iter++;
|
||||||
}
|
}
|
||||||
|
@ -380,18 +393,31 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set module description */
|
||||||
if (module_description != "") {
|
if (module_description != "") {
|
||||||
module->setDescription (module_description);
|
module->setDescription (module_description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Save module data as an environment variable */
|
||||||
if (module_save != "") {
|
if (module_save != "") {
|
||||||
module->setSave (module_save);
|
module->setSave (module_save);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Async module */
|
||||||
if (module_async != "") {
|
if (module_async != "") {
|
||||||
module->setAsync (true);
|
module->setAsync (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Module condition */
|
||||||
|
if (condition_list.size () > 0) {
|
||||||
|
condition_iter = condition_list.begin ();
|
||||||
|
for (condition_iter = condition_list.begin ();
|
||||||
|
condition_iter != condition_list.end ();
|
||||||
|
condition_iter++) {
|
||||||
|
module->addCondition (*condition_iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Plugins do not have a module type */
|
/* Plugins do not have a module type */
|
||||||
if (module_plugin == "") {
|
if (module_plugin == "") {
|
||||||
type = Pandora_Module::parseModuleTypeFromString (module_type);
|
type = Pandora_Module::parseModuleTypeFromString (module_type);
|
||||||
|
|
|
@ -282,9 +282,11 @@ Pandora_Windows_Service::copyTentacleDataFile (string host,
|
||||||
WaitForSingleObject(pi.hProcess, INFINITE);
|
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||||
GetExitCodeProcess (pi.hProcess, &rc);
|
GetExitCodeProcess (pi.hProcess, &rc);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
|
CloseHandle (pi.hProcess);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CloseHandle (pi.hProcess);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -862,6 +864,9 @@ Pandora_Windows_Service::pandora_run () {
|
||||||
module->exportDataOutput ();
|
module->exportDataOutput ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Evaluate module conditions */
|
||||||
|
module->evaluateConditions ();
|
||||||
|
|
||||||
this->modules->goNext ();
|
this->modules->goNext ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue