diff --git a/pandora_agents/win32/ChangeLog b/pandora_agents/win32/ChangeLog index 46bf54b0f5..59290e17dd 100644 --- a/pandora_agents/win32/ChangeLog +++ b/pandora_agents/win32/ChangeLog @@ -1,3 +1,23 @@ +2008-04-02 Esteban Sanchez + + * pandora_agent_conf.[cc,h]: Object adapted to be a singleton so it + could be used in many parts of the code who can't access to it before. + + * ftp/pandora_ftp_test.cc, ssh/pandora_ssh_test.cc: Adapted to + configuration object singleton. + + * modules/pandora_module_odbc.[cc,h]: Added to repository. Implements + a ODBC interface to make SQL queries. + + * modules/pandora_module.[cc,h], modules/pandora_module_list.cc, + modules/pandora_module_factory.cc: Added ODBC module support. + + * bin/pandora_agent.conf: Added a ODBC module example. + + * PandoraAgent.dev: Added new files to project. + + * bin/PandoraAgent.exe: Updated to last commit. + 2008-04-02 Manuel Arostegui * installer/pandora_1.3.mpi: Adapted for the 1.3.1 Windows Installer diff --git a/pandora_agents/win32/PandoraAgent.dev b/pandora_agents/win32/PandoraAgent.dev index a610c7e9ca..b591dda2c4 100644 --- a/pandora_agents/win32/PandoraAgent.dev +++ b/pandora_agents/win32/PandoraAgent.dev @@ -1,7 +1,7 @@ [Project] FileName=PandoraAgent.dev Name=PandoraAgent -UnitCount=69 +UnitCount=71 Type=1 Ver=1 ObjFiles= @@ -12,7 +12,7 @@ ResourceIncludes= MakeIncludes= Compiler= CppCompiler= -Linker=-lole32_@@_-loleaut32_@@_-luuid_@@_-lpsapi_@@_-lwsock32_@@_-lz_@@_-liphlpapi_@@_-lnetapi32_@@_-lws2_32_@@_-lcrypto_@@_-lgdi32_@@_-lcurldll_@@_ +Linker=-lole32_@@_-loleaut32_@@_-luuid_@@_-lpsapi_@@_-lwsock32_@@_-lz_@@_-liphlpapi_@@_-lnetapi32_@@_-lws2_32_@@_-lcrypto_@@_-lodbc++_@@_-lgdi32_@@_-lcurldll_@@_ IsCpp=1 Icon= ExeOutput= @@ -27,7 +27,7 @@ CustomMakefile= IncludeVersionInfo=0 SupportXPThemes=0 CompilerSet=0 -CompilerSettings=0000000000000001000000 +CompilerSettings=0000000000000000000000 [Unit1] FileName=main.cc @@ -737,3 +737,23 @@ Priority=1000 OverrideBuildCmd=0 BuildCmd= +[Unit70] +FileName=modules\pandora_module_odbc.cc +CompileCpp=1 +Folder=Modules +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + +[Unit71] +FileName=modules\pandora_module_odbc.h +CompileCpp=1 +Folder=Modules +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/pandora_agents/win32/bin/PandoraAgent.exe b/pandora_agents/win32/bin/PandoraAgent.exe index 90d2c3f4c1..4d9b1c96e4 100755 Binary files a/pandora_agents/win32/bin/PandoraAgent.exe and b/pandora_agents/win32/bin/PandoraAgent.exe differ diff --git a/pandora_agents/win32/bin/pandora_agent.conf b/pandora_agents/win32/bin/pandora_agent.conf index 8e79366fbe..f99365a7cc 100644 --- a/pandora_agents/win32/bin/pandora_agent.conf +++ b/pandora_agents/win32/bin/pandora_agent.conf @@ -35,6 +35,12 @@ server_port 41121 # Debug mode do not copy XML data files to server and stop executing after first one # debug 1 +# ODBC connections +# Configuring "ExampleDSN" DSN. Notice that this DSN connection must be configured +# under Control panel -> Administrative tools -> ODBC -> DSN +odbc_ExampleDSN_username UserNameForDsn +odbc_ExampleDSN_password Password1234 + # Module Definition # ================= @@ -146,6 +152,26 @@ module_end # More examples, uncomment (removing #) to use them # ================================================= +# ODBC query example using ExampleDSN connection defined above. +# This module gets the first row in example_table. +#module_begin +#module_name SQL query example +#module_type generic_string +#module_odbc ExampleDSN +#module_odbc_query SELECT * FROM example_table +#module_description The first row of example_table +#module_end + +# ODBC query example using ExampleDSN connection defined above. +# This module gets the first row in example_table +#module_begin +#module_name SecondSQL query example +#module_type generic_data +#module_odbc ExampleDSN +#module_odbc_query SELECT punctuation FROM example_table WHERE id = 3 +#module_description The punctuation row of example_tab where id is 3 +#module_end + #Free space on disk D: #module_begin #module_name FreeDiskD diff --git a/pandora_agents/win32/ftp/pandora_ftp_test.cc b/pandora_agents/win32/ftp/pandora_ftp_test.cc index 39ec399bd8..48c8375c22 100644 --- a/pandora_agents/win32/ftp/pandora_ftp_test.cc +++ b/pandora_agents/win32/ftp/pandora_ftp_test.cc @@ -40,7 +40,8 @@ Pandora_FTP_Test::Pandora_FTP_Test () { conf_file = Pandora::getPandoraInstallDir (); conf_file += "pandora_agent.conf"; - conf = new Pandora_Agent_Conf (conf_file); + conf = Pandora::Pandora_Agent_Conf::getInstance (); + conf->setFile (conf_file); ftp_client = new FTP::Pandora_Ftp_Client (); } diff --git a/pandora_agents/win32/modules/pandora_module.cc b/pandora_agents/win32/modules/pandora_module.cc index 24760e0db6..63d4a71f45 100644 --- a/pandora_agents/win32/modules/pandora_module.cc +++ b/pandora_agents/win32/modules/pandora_module.cc @@ -94,6 +94,8 @@ Pandora_Module::parseModuleKindFromString (string kind) { return MODULE_FREEMEMORY; } else if (kind == module_cpuusage_str) { return MODULE_CPUUSAGE; + } else if (kind == module_odbc_str) { + return MODULE_ODBC; } else { return MODULE_0; } diff --git a/pandora_agents/win32/modules/pandora_module.h b/pandora_agents/win32/modules/pandora_module.h index 00c30e92dd..88519a1854 100644 --- a/pandora_agents/win32/modules/pandora_module.h +++ b/pandora_agents/win32/modules/pandora_module.h @@ -64,8 +64,9 @@ namespace Pandora_Modules { * service */ MODULE_FREEDISK, /**< The module checks the free */ MODULE_CPUUSAGE, /**< The module checks the CPU usage */ - MODULE_FREEMEMORY /**< The module checks the amount of + MODULE_FREEMEMORY, /**< The module checks the amount of * freememory in the system */ + MODULE_ODBC /**< The module performs a SQL query via ODBC */ } Module_Kind; const string module_exec_str = "module_exec"; @@ -74,6 +75,7 @@ namespace Pandora_Modules { const string module_freedisk_str = "module_freedisk"; const string module_freememory_str = "module_freememory"; const string module_cpuusage_str = "module_cpuusage"; + const string module_odbc_str = "module_odbc"; /** * Pandora module super-class exception. diff --git a/pandora_agents/win32/modules/pandora_module_factory.cc b/pandora_agents/win32/modules/pandora_module_factory.cc index fdbf25615a..d29185f259 100644 --- a/pandora_agents/win32/modules/pandora_module_factory.cc +++ b/pandora_agents/win32/modules/pandora_module_factory.cc @@ -26,6 +26,7 @@ #include "pandora_module_freedisk.h" #include "pandora_module_freememory.h" #include "pandora_module_cpuusage.h" +#include "pandora_module_odbc.h" #include "../pandora_strutils.h" #include @@ -42,9 +43,11 @@ using namespace Pandora_Strutils; #define TOKEN_FREEDISK ("module_freedisk ") #define TOKEN_FREEMEMORY ("module_freememory") #define TOKEN_CPUUSAGE ("module_cpuusage ") +#define TOKEN_ODBC ("module_odbc ") #define TOKEN_MAX ("module_max ") #define TOKEN_MIN ("module_min ") #define TOKEN_DESCRIPTION ("module_description ") +#define TOKEN_ODBC_QUERY ("module_odbc_query ") string parseLine (string line, string token) { @@ -77,7 +80,8 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) { string module_name, module_type, module_exec; string module_min, module_max, module_description; string module_interval, module_proc, module_service; - string module_freedisk, module_cpuusage, module_freememory; + string module_freedisk, module_cpuusage, module_odbc; + string module_odbc_query, module_dsn, module_freememory; Pandora_Module *module; bool numeric; Module_Type type; @@ -91,6 +95,8 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) { module_exec = ""; module_proc = ""; module_service = ""; + module_odbc = ""; + module_odbc_query = ""; stringtok (tokens, definition, "\n"); @@ -128,6 +134,9 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) { if (module_cpuusage == "") { module_cpuusage = parseLine (line, TOKEN_CPUUSAGE); } + if (module_odbc == "") { + module_odbc = parseLine (line, TOKEN_ODBC); + } if (module_max == "") { module_max = parseLine (line, TOKEN_MAX); } @@ -137,10 +146,14 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) { if (module_description == "") { module_description = parseLine (line, TOKEN_DESCRIPTION); } - + if (module_odbc_query == "") { + module_odbc_query = parseLine (line, TOKEN_ODBC_QUERY); + } + iter++; } - + + /* Create module objects */ if (module_exec != "") { module = new Pandora_Module_Exec (module_name, module_exec); @@ -153,10 +166,8 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) { } else if (module_freedisk != "") { module = new Pandora_Module_Freedisk (module_name, module_freedisk); - } else if (module_freememory != "") { module = new Pandora_Module_Freememory (module_name); - } else if (module_cpuusage != "") { int cpu_id; @@ -170,12 +181,15 @@ Pandora_Module_Factory::getModuleFromDefinition (string definition) { module = new Pandora_Module_Cpuusage (module_name, cpu_id); - - } - else { + + } else if (module_odbc != "") { + module = new Pandora_Module_Odbc (module_name, + module_odbc, + module_odbc_query); + } else { return NULL; } - + if (module_description != "") { module->setDescription (module_description); } diff --git a/pandora_agents/win32/modules/pandora_module_list.cc b/pandora_agents/win32/modules/pandora_module_list.cc index 4793789d98..d7c95dba28 100644 --- a/pandora_agents/win32/modules/pandora_module_list.cc +++ b/pandora_agents/win32/modules/pandora_module_list.cc @@ -26,6 +26,7 @@ #include "pandora_module_freedisk.h" #include "pandora_module_freememory.h" #include "pandora_module_cpuusage.h" +#include "pandora_module_odbc.h" #include using namespace std; @@ -113,10 +114,12 @@ Pandora_Modules::Pandora_Module_List::parseModuleDefinition (string definition) Pandora_Module_Freedisk *module_freedisk; Pandora_Module_Cpuusage *module_cpuusage; Pandora_Module_Freememory *module_freememory; + Pandora_Module_Odbc *module_odbc; module = Pandora_Module_Factory::getModuleFromDefinition (definition); if (module != NULL) { + cout << module->getModuleKind () << endl; switch (module->getModuleKind ()) { case MODULE_EXEC: module_exec = (Pandora_Module_Exec *) module; @@ -149,8 +152,14 @@ Pandora_Modules::Pandora_Module_List::parseModuleDefinition (string definition) module_cpuusage = (Pandora_Module_Cpuusage *) module; modules->push_back (module_cpuusage); + break; + case MODULE_ODBC: + module_odbc = (Pandora_Module_Odbc *) module; + modules->push_back (module_odbc); + cout << "ASDS" << endl; break; default: + cout << "NONE" << endl; break; } } diff --git a/pandora_agents/win32/modules/pandora_module_odbc.cc b/pandora_agents/win32/modules/pandora_module_odbc.cc new file mode 100755 index 0000000000..30dfe26641 --- /dev/null +++ b/pandora_agents/win32/modules/pandora_module_odbc.cc @@ -0,0 +1,209 @@ +/* Pandora ODBC module. These modules check the free space in a + logical drive. + + Copyright (C) 2006 Artica ST. + Written by Esteban Sanchez. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "pandora_module_odbc.h" +#include "../pandora_strutils.h" +#include "../pandora_agent_conf.h" +#include +#include +#include +#include +#include + +using namespace Pandora; +using namespace Pandora_Modules; +using namespace Pandora_Strutils; + +/** + * Creates a Pandora_Module_Odbc object. + * + * @param name Module name + * @param dsn ODBC dsn string + * @param query SQL query to do + */ +Pandora_Module_Odbc::Pandora_Module_Odbc (string name, + string dsn, + string query) + : Pandora_Module (name) { + + Pandora_Agent_Conf::Pandora_Agent_Conf *conf; + + conf = Pandora_Agent_Conf::getInstance (); + + this->setKind (module_odbc_str); + this->dsn = dsn; + this->username = conf->getValue ("odbc_" + dsn + "_username"); + this->password = conf->getValue ("odbc_" + dsn + "_password"); + this->query = query; +} + +/** + * Set DSN ODBC connection + * + * @param dsn DSN to set. + */ +void +Pandora_Module_Odbc::setDsn (string dsn) { + this->dsn = dsn; +} + +/** + * Set ODBC username. + * + * @param username Username to set. + */ +void +Pandora_Module_Odbc::setUsername (string username) { + this->username = username; +} + +/** + * Set ODBC password. + * + * @param password Password to set. + */ +void +Pandora_Module_Odbc::setPassword (string password) { + this->password = password; +} + +/** + * Set module SQL query to ODBC connection + * + * @param query SQL query to launch. + */ +void +Pandora_Module_Odbc::setQuery (string query) { + this->query = query; +} + +/** + * Get DSN ODBC string. + * + * @return DSN ODBC string. + */ +string +Pandora_Module_Odbc::getDsn () { + return this->dsn; +} + +/** + * Get ODBC password. + * + * @return Connection password + */ +string +Pandora_Module_Odbc::getPassword () { + return this->password; +} + +/** + * Get ODBC username. + * + * @return + */ +string +Pandora_Module_Odbc::getUsername () { + return this->username; +} + +/** + * Get SQL module query. + * + * @return SQL module query + */ +string +Pandora_Module_Odbc::getQuery () { + return this->query; +} + +/** + * Perform the query into the database and set the output value of the + * module. + */ +void +Pandora_Module_Odbc::doQuery () { + string retval; + auto_ptr statement; + auto_ptr results; + ResultSetMetaData *metadata; + int columns; + + statement = auto_ptr (this->con->createStatement ()); + results = auto_ptr (statement->executeQuery (query)); + metadata = results->getMetaData (); + columns = metadata->getColumnCount (); + + if (results->next ()) { + if (this->getTypeInt () == TYPE_GENERIC_DATA_STRING) { + for (int i = 1; i <= columns; i++) { + this->output += results->getString (i); + if (i + 1 <= columns) + this->output += " | "; + } + } else { + this->output = longtostr (results->getLong (1)); + } + } +} + +void +Pandora_Module_Odbc::run () { + try { + Pandora_Module::run (); + } catch (Interval_Not_Fulfilled e) { + return; + } + + if (this->query == "") { + pandoraLog ("Error on module ODBC '%s': No query to execute", + this->module_name.c_str ()); + return; + } + + if (this->dsn == "") { + pandoraLog ("Error on module ODBC '%s': No DSN to connect to", + this->module_name.c_str ()); + return; + } + + if (this->username == "") { + pandoraLog ("Error on module ODBC '%s': No username to connect to DSN %s. " + "Add %s_username parameter to configuration file", + this->module_name.c_str (), this->dsn.c_str (), this->dsn.c_str ()); + return; + } + + try { + pandoraLog ("Module ODBC connecting to dsn=%s, uid=%s, pwd=****", + this->dsn.c_str (), this->username.c_str ()); + this->con = DriverManager::getConnection (this->dsn, this->username, this->password); + + this->doQuery (); + delete this->con; + DriverManager::shutdown(); + } catch (SQLException &e) { + pandoraLog ("Error on module ODBC '%s': %s", this->module_name.c_str (), e.getMessage().c_str ()); + this->has_output = false; + } catch (Pandora_Exception e) { + this->has_output = false; + } +} diff --git a/pandora_agents/win32/modules/pandora_module_odbc.h b/pandora_agents/win32/modules/pandora_module_odbc.h new file mode 100755 index 0000000000..42978910c0 --- /dev/null +++ b/pandora_agents/win32/modules/pandora_module_odbc.h @@ -0,0 +1,63 @@ +/* Pandora ODBC module. These modules check the free space in a + logical drive. + + Copyright (C) 2006 Artica ST. + Written by Esteban Sanchez. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __PANDORA_MODULE_ODBC_H__ +#define __PANDORA_MODULE_ODBC_H__ + +#include "pandora_module.h" +#include + +using namespace odbc; + +namespace Pandora_Modules { + /** + * Module to retrieve a value based on a SQL query to an ODBC + * connection. + */ + class Pandora_Module_Odbc : public Pandora_Module { + private: + string dsn; + string username; + string password; + string query; + Connection *con; + + void doQuery (); + public: + Pandora_Module_Odbc (string name, + string dsn, + string query); + + void setDsn (string dsn); + void setUsername (string username); + void setPassword (string password); + void setQuery (string query); + + string getDsn (); + string getPassword (); + string getUsername (); + string getQuery (); + + void run (); + }; +} + +#endif diff --git a/pandora_agents/win32/pandora_agent_conf.cc b/pandora_agents/win32/pandora_agent_conf.cc index 58a4c44b84..7431bfcfdf 100644 --- a/pandora_agents/win32/pandora_agent_conf.cc +++ b/pandora_agents/win32/pandora_agent_conf.cc @@ -27,8 +27,29 @@ using namespace Pandora; #define MAX_KEYS 100 +Pandora::Pandora_Agent_Conf::Pandora_Agent_Conf () { + this->key_values = NULL; +} + /** - * Creates a new Pandora_Agent_Conf. + * Destroy a Pandora_Agent_Conf object. + */ +Pandora::Pandora_Agent_Conf::~Pandora_Agent_Conf () { + delete key_values; +} + +Pandora_Agent_Conf * +Pandora::Pandora_Agent_Conf::getInstance () { + static Pandora_Agent_Conf *conf = NULL; + + if (conf) + return conf; + conf = new Pandora_Agent_Conf (); + return conf; +} + +/** + * Sets configuration file to Pandora_Agent_Conf object instance. * * It parses the filename and initialize the internal structures * of configuration values. The configuration file consist of a number of @@ -38,11 +59,14 @@ using namespace Pandora; * * @param filename Configuration file to open. */ -Pandora::Pandora_Agent_Conf::Pandora_Agent_Conf (string filename) { - ifstream file (filename.c_str ()); +void +Pandora::Pandora_Agent_Conf::setFile (string filename) { + ifstream file (filename.c_str ()); string buffer; unsigned int pos; - + + if (this->key_values) + delete this->key_values; this->key_values = new list (); if (!file.is_open ()) { @@ -68,13 +92,6 @@ Pandora::Pandora_Agent_Conf::Pandora_Agent_Conf (string filename) { file.close (); } -/** - * Destroy a Pandora_Agent_Conf object. - */ -Pandora::Pandora_Agent_Conf::~Pandora_Agent_Conf () { - delete key_values; -} - /** * Queries for a configuration value. * diff --git a/pandora_agents/win32/pandora_agent_conf.h b/pandora_agents/win32/pandora_agent_conf.h index 6ac5ac0429..05d7ca1241 100644 --- a/pandora_agents/win32/pandora_agent_conf.h +++ b/pandora_agents/win32/pandora_agent_conf.h @@ -38,12 +38,14 @@ namespace Pandora { class Pandora_Agent_Conf { private: list *key_values; + + Pandora_Agent_Conf (); public: - Pandora_Agent_Conf (string filename); + static Pandora_Agent_Conf *getInstance (); - ~Pandora_Agent_Conf (); - - string getValue (const string key); + ~Pandora_Agent_Conf (); + void setFile (string filename); + string getValue (const string key); }; } diff --git a/pandora_agents/win32/pandora_windows_service.cc b/pandora_agents/win32/pandora_windows_service.cc index 132b2076b4..9b5f4a6a43 100644 --- a/pandora_agents/win32/pandora_windows_service.cc +++ b/pandora_agents/win32/pandora_windows_service.cc @@ -102,7 +102,8 @@ Pandora_Windows_Service::pandora_init () { conf_file = Pandora::getPandoraInstallDir (); conf_file += "pandora_agent.conf"; - this->conf = new Pandora::Pandora_Agent_Conf (conf_file); + this->conf = Pandora::Pandora_Agent_Conf::getInstance (); + this->conf->setFile (conf_file); this->modules = new Pandora_Module_List (conf_file); /* Get the interval value (in minutes) and set it to the service */ diff --git a/pandora_agents/win32/ssh/pandora_ssh_test.cc b/pandora_agents/win32/ssh/pandora_ssh_test.cc index a3d3b23dfc..ddcf25260c 100644 --- a/pandora_agents/win32/ssh/pandora_ssh_test.cc +++ b/pandora_agents/win32/ssh/pandora_ssh_test.cc @@ -37,7 +37,8 @@ Pandora_SSH_Test::Pandora_SSH_Test () { conf_file = Pandora::getPandoraInstallDir (); conf_file += "pandora_agent.conf"; - conf = new Pandora::Pandora_Agent_Conf (conf_file); + conf = Pandora::Pandora_Agent_Conf::getInstance (); + conf->setFile (conf_file); ssh_client = new SSH::Pandora_Ssh_Client (); }