-lcrypto \
-lpthread
PROG = ssmd # SNMP Switch Management Daemon
-VERSION = 1.1.7
+VERSION = 1.2.0
SOURCES = src/main.cpp \
src/pidfile.cpp \
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; }
std::string _dataURL;
+ std::string _scriptBase;
+ bool _dumpScripts;
+
friend class SettingsParser;
};
_upProfileId(1),
_downProfileId(2),
_maxACLPerPDU(50),
- _dataURL()
+ _dumpScripts(false)
{
}
_upProfileId(rvalue._upProfileId),
_downProfileId(rvalue._downProfileId),
_maxACLPerPDU(rvalue._maxACLPerPDU),
- _dataURL(rvalue._dataURL)
+ _dataURL(rvalue._dataURL),
+ _scriptBase(rvalue._scriptBase),
+ _dumpScripts(rvalue._dumpScripts)
{
}
_downProfileId = rvalue._downProfileId;
_maxACLPerPDU = rvalue._maxACLPerPDU;
_dataURL = rvalue._dataURL;
+ _scriptBase = rvalue._scriptBase;
+ _dumpScripts = rvalue._dumpScripts;
return *this;
}
("down-profile-id", po::value<unsigned>(), "switch's download profile id")
("max-acl-per-pdu", po::value<size_t>(), "maximum ACL's per PDU")
("data-url", po::value<std::string>(), "data access URL")
+ ("script-base", po::value<std::string>(), "base dir for scripts")
+ ("dump-scripts", "dump SNMP command into shell scripts")
("version,v", "show ssmd version and exit")
;
}
{
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<std::string>();
- }
if (!_settings._isHelp &&
!_settings._isVersion) {
}
}
- 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<std::string>();
- }
-
- if (vm.count("pid-file")) {
+ if (vm.count("pid-file"))
_settings._PIDFile = vm["pid-file"].as<std::string>();
- }
-
- if (vm.count("switch-sync-interval")) {
+ if (vm.count("switch-sync-interval"))
_settings._switchSyncInterval = vm["switch-sync-interval"].as<time_t>();
- }
-
- if (vm.count("info-sync-interval")) {
+ if (vm.count("info-sync-interval"))
_settings._infoSyncInterval = vm["info-sync-interval"].as<time_t>();
- }
-
- if (vm.count("up-profile-id")) {
+ if (vm.count("up-profile-id"))
_settings._upProfileId = vm["up-profile-id"].as<unsigned>();
- }
-
- if (vm.count("down-profile-id")) {
+ if (vm.count("down-profile-id"))
_settings._downProfileId = vm["down-profile-id"].as<unsigned>();
- }
-
- if (vm.count("max-acl-per-pdu")) {
+ if (vm.count("max-acl-per-pdu"))
_settings._downProfileId = vm["max-acl-per-pdu"].as<unsigned>();
- }
-
- if (vm.count("data-url")) {
+ if (vm.count("data-url"))
_settings._dataURL = vm["data-url"].as<std::string>();
- }
+ if (vm.count("script-base"))
+ _settings._scriptBase = vm["script-base"].as<std::string>();
+ if (vm.count("dump-scripts"))
+ _settings._dumpScripts = true;
}
void SettingsParser::reloadConfig()
typedef std::map<std::string, PairsType> SectionsType;
template <typename Iterator>
-struct IniGrammar
+struct IniGrammar
: qi::grammar<Iterator, SectionsType()>
{
IniGrammar()
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()) {
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<time_t>(res);
- }
- if (fieldValue(data, "sync", "info_interval", res)){
+ if (fieldValue(data, "sync", "info_interval", res))
_settings._infoSyncInterval = boost::lexical_cast<time_t>(res);
- }
- if (fieldValue(data, "sync", "up_profile_id", res)){
+ if (fieldValue(data, "sync", "up_profile_id", res))
_settings._upProfileId = boost::lexical_cast<unsigned>(res);
- }
- if (fieldValue(data, "sync", "down_profile_id", res)){
+ if (fieldValue(data, "sync", "down_profile_id", res))
_settings._downProfileId = boost::lexical_cast<unsigned>(res);
- }
- if (fieldValue(data, "sync", "max_acl_per_pdu", res)){
+ if (fieldValue(data, "sync", "max_acl_per_pdu", res))
_settings._maxACLPerPDU = boost::lexical_cast<size_t>(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");
}
}
{
- 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()) {
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) {
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;
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;
}