From 8481ea2740db7758f5533abfdbdbacce1ac6b919 Mon Sep 17 00:00:00 2001 From: Maxim Mamontov Date: Wed, 17 Sep 2014 20:46:43 +0300 Subject: [PATCH] Control dumping snmp scripts. --- Makefile | 2 +- include/settings.h | 6 +++++ include/settings.inl.h | 8 +++++-- src/settings.cpp | 48 ++++++++++++++------------------------ src/settingsfileparser.cpp | 32 +++++++++++-------------- src/switch.cpp | 37 ++++++++++++++++++++--------- 6 files changed, 70 insertions(+), 63 deletions(-) diff --git a/Makefile b/Makefile index 45aef9a..8959720 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ LIBS = 3rdparty/snmp++/libsnmp++.a \ -lcrypto \ -lpthread PROG = ssmd # SNMP Switch Management Daemon -VERSION = 1.1.7 +VERSION = 1.2.0 SOURCES = src/main.cpp \ src/pidfile.cpp \ diff --git a/include/settings.h b/include/settings.h index c88f94a..041453a 100644 --- a/include/settings.h +++ b/include/settings.h @@ -40,6 +40,9 @@ class Settings { const std::string & dataURL() const throw() { return _dataURL; } + const std::string & scriptBase() const throw() { return _scriptBase; } + bool dumpScripts() const throw() { return _dumpScripts; } + // Setters void setIsHelp(bool value) throw() { _isHelp = value; } void setIsVersion(bool value) throw() { _isVersion = value; } @@ -80,6 +83,9 @@ class Settings { std::string _dataURL; + std::string _scriptBase; + bool _dumpScripts; + friend class SettingsParser; }; diff --git a/include/settings.inl.h b/include/settings.inl.h index dbc275c..e922c82 100644 --- a/include/settings.inl.h +++ b/include/settings.inl.h @@ -20,7 +20,7 @@ Settings::Settings() _upProfileId(1), _downProfileId(2), _maxACLPerPDU(50), - _dataURL() + _dumpScripts(false) { } @@ -38,7 +38,9 @@ Settings::Settings(const Settings & rvalue) _upProfileId(rvalue._upProfileId), _downProfileId(rvalue._downProfileId), _maxACLPerPDU(rvalue._maxACLPerPDU), - _dataURL(rvalue._dataURL) + _dataURL(rvalue._dataURL), + _scriptBase(rvalue._scriptBase), + _dumpScripts(rvalue._dumpScripts) { } @@ -63,6 +65,8 @@ const Settings & Settings::operator=(const Settings & rvalue) _downProfileId = rvalue._downProfileId; _maxACLPerPDU = rvalue._maxACLPerPDU; _dataURL = rvalue._dataURL; + _scriptBase = rvalue._scriptBase; + _dumpScripts = rvalue._dumpScripts; return *this; } diff --git a/src/settings.cpp b/src/settings.cpp index 6e3a791..897793c 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -21,6 +21,8 @@ SettingsParser::SettingsParser() ("down-profile-id", po::value(), "switch's download profile id") ("max-acl-per-pdu", po::value(), "maximum ACL's per PDU") ("data-url", po::value(), "data access URL") + ("script-base", po::value(), "base dir for scripts") + ("dump-scripts", "dump SNMP command into shell scripts") ("version,v", "show ssmd version and exit") ; } @@ -29,14 +31,13 @@ void SettingsParser::init(int argc, char * argv[]) { po::variables_map vm; po::store(po::parse_command_line(argc, argv, _desc), vm); - po::notify(vm); + po::notify(vm); _settings._isHelp = vm.count("help"); _settings._isVersion = vm.count("version"); - if (vm.count("config")) { + if (vm.count("config")) _settings._configFile = vm["config"].as(); - } if (!_settings._isHelp && !_settings._isVersion) { @@ -48,44 +49,31 @@ void SettingsParser::init(int argc, char * argv[]) } } - if (vm.count("debug")) { + if (vm.count("debug")) _settings._isDebug = true; - } - if (vm.count("daemon")) { + if (vm.count("daemon")) _settings._isDaemon = true; - } - if (vm.count("log-file")) { + if (vm.count("log-file")) _settings._logFile = vm["log-file"].as(); - } - - if (vm.count("pid-file")) { + if (vm.count("pid-file")) _settings._PIDFile = vm["pid-file"].as(); - } - - if (vm.count("switch-sync-interval")) { + if (vm.count("switch-sync-interval")) _settings._switchSyncInterval = vm["switch-sync-interval"].as(); - } - - if (vm.count("info-sync-interval")) { + if (vm.count("info-sync-interval")) _settings._infoSyncInterval = vm["info-sync-interval"].as(); - } - - if (vm.count("up-profile-id")) { + if (vm.count("up-profile-id")) _settings._upProfileId = vm["up-profile-id"].as(); - } - - if (vm.count("down-profile-id")) { + if (vm.count("down-profile-id")) _settings._downProfileId = vm["down-profile-id"].as(); - } - - if (vm.count("max-acl-per-pdu")) { + if (vm.count("max-acl-per-pdu")) _settings._downProfileId = vm["max-acl-per-pdu"].as(); - } - - if (vm.count("data-url")) { + if (vm.count("data-url")) _settings._dataURL = vm["data-url"].as(); - } + if (vm.count("script-base")) + _settings._scriptBase = vm["script-base"].as(); + if (vm.count("dump-scripts")) + _settings._dumpScripts = true; } void SettingsParser::reloadConfig() diff --git a/src/settingsfileparser.cpp b/src/settingsfileparser.cpp index bf2fda2..a211307 100644 --- a/src/settingsfileparser.cpp +++ b/src/settingsfileparser.cpp @@ -16,7 +16,7 @@ typedef std::map PairsType; typedef std::map SectionsType; template -struct IniGrammar +struct IniGrammar : qi::grammar { IniGrammar() @@ -77,9 +77,8 @@ using SSMD::SettingsParser; void SettingsParser::parseFile(const std::string & fileName) { std::ifstream in(fileName.c_str()); - if (!in) { + if (!in) throw std::runtime_error("Can't open file"); - } std::string text; while(!in.eof()) { @@ -101,28 +100,23 @@ void SettingsParser::parseFile(const std::string & fileName) std::string res; _settings._isDaemon = fieldExists(data, "general", "daemon"); _settings._isDebug = fieldExists(data, "general", "debug"); - if (fieldValue(data, "general", "log_file", res)){ + if (fieldValue(data, "general", "log_file", res)) _settings._logFile = res; - } - if (fieldValue(data, "general", "pid_file", res)){ + if (fieldValue(data, "general", "pid_file", res)) _settings._PIDFile = res; - } - if (fieldValue(data, "sync", "switch_interval", res)){ + if (fieldValue(data, "sync", "switch_interval", res)) _settings._switchSyncInterval = boost::lexical_cast(res); - } - if (fieldValue(data, "sync", "info_interval", res)){ + if (fieldValue(data, "sync", "info_interval", res)) _settings._infoSyncInterval = boost::lexical_cast(res); - } - if (fieldValue(data, "sync", "up_profile_id", res)){ + if (fieldValue(data, "sync", "up_profile_id", res)) _settings._upProfileId = boost::lexical_cast(res); - } - if (fieldValue(data, "sync", "down_profile_id", res)){ + if (fieldValue(data, "sync", "down_profile_id", res)) _settings._downProfileId = boost::lexical_cast(res); - } - if (fieldValue(data, "sync", "max_acl_per_pdu", res)){ + if (fieldValue(data, "sync", "max_acl_per_pdu", res)) _settings._maxACLPerPDU = boost::lexical_cast(res); - } - if (fieldValue(data, "sync", "data_url", res)){ + if (fieldValue(data, "sync", "data_url", res)) _settings._dataURL = res; - } + if (fieldValue(data, "sync", "script_base", res)) + _settings._scriptBase = res; + _settings._dumpScripts = fieldExists(data, "sync", "dump_scripts"); } diff --git a/src/switch.cpp b/src/switch.cpp index 444324b..71917ed 100644 --- a/src/switch.cpp +++ b/src/switch.cpp @@ -130,21 +130,32 @@ void Switch::sync() } { - std::string fileName(_ip + ".sh"); + std::ostream * stream = NULL; + std::string fileName(_settings.scriptBase() + "/" + _ip + ".sh"); std::string newFileName(fileName + ".new"); - std::ofstream script(newFileName.c_str()); - script << "#!/bin/sh\n"; - if (!dropACLs(target, script)) { + + if (_settings.dumpScripts()) { + stream = new std::ofstream(newFileName.c_str()); + *stream << "#!/bin/sh\n"; + } else { + stream = new std::stringstream; + } + + if (!dropACLs(target, *stream)) { logger << "Switch::sync() - failed to drop ACLs for the switch '" << _ip << "'" << std::endl; + delete stream; return; } - if (!createACLs(target, script)) { + if (!createACLs(target, *stream)) { logger << "Switch::sync() - failed to create ACLs for the switch '" << _ip << "'" << std::endl; + delete stream; return; } - script.close(); - rename(newFileName.c_str(), fileName.c_str()); + + delete stream; + if (_settings.dumpScripts()) + rename(newFileName.c_str(), fileName.c_str()); } if (_settings.isDebug()) { @@ -217,7 +228,8 @@ bool Switch::dropACLsByTable(const CTarget & target, unsigned profileId, const S size_t chunks = aclsList.size() / _settings.maxACLPerPDU() + 1; for (size_t i = 0; i < chunks && it != aclsList.end(); ++i) { Pdu pdu; - stream << "snmpset -v2c -cgts_community_w " << _ip; + if (_settings.dumpScripts()) + stream << "snmpset -v2c -c" << _writeCommunity << " " << _ip; for (size_t j = 0; j < _settings.maxACLPerPDU() && it != aclsList.end(); ++j, ++it) { int id; if (int c = it->get_value(id) != SNMP_CLASS_SUCCESS) { @@ -230,9 +242,11 @@ bool Switch::dropACLsByTable(const CTarget & target, unsigned profileId, const S Vb vb(Oid(dropACLOid.c_str())); vb.set_value(int(6)); pdu += vb; - stream << " " << dropACLOid << " i 6"; + if (_settings.dumpScripts()) + stream << " " << dropACLOid << " i 6"; } - stream << "\n"; + if (_settings.dumpScripts()) + stream << "\n"; if (int c = _snmp.set(pdu, target) != SNMP_CLASS_SUCCESS) { if (c != SNMP_ERROR_TOO_BIG) { logger << "Switch::dropACLsByTable() - failed to invoke Snmp::set for the switch '" << _ip << "'. Error message: '" << Snmp::error_msg(c) << "'" << std::endl; @@ -260,7 +274,8 @@ bool Switch::createACLs(const CTarget & target, std::ostream & stream) pdu.clear(); _aclsCreated = true; ++pos; - stream << "snmpset -v2c -cgts_community_w " << _ip << " " << *it << "\n"; + if (_settings.dumpScripts()) + stream << "snmpset -v2c -c" << _writeCommunity << " " << _ip << " " << *it << "\n"; } return true; } -- 2.43.2