Fix filter parsing for values containing white spaces.

Refs #4433
This commit is contained in:
Michael Friedrich 2013-11-05 12:31:30 +01:00
parent 0eb5daaad9
commit 5718cbebe4
2 changed files with 84 additions and 8 deletions

View File

@ -334,6 +334,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
/* States - TODO refactor */
if (boost::algorithm::contains(type, "INITIAL HOST STATE")) {
if (tokens.size() < 5)
return Dictionary::Ptr();
log_class = LogClassState;
log_type = LogTypeHostInitialState;
@ -344,6 +347,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
plugin_output = tokens[4];
}
else if (boost::algorithm::contains(type, "CURRENT HOST STATE")) {
if (tokens.size() < 5)
return Dictionary::Ptr();
log_class = LogClassState;
log_type = LogTypeHostCurrentState;
@ -354,6 +360,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
plugin_output = tokens[4];
}
else if (boost::algorithm::contains(type, "HOST ALERT")) {
if (tokens.size() < 5)
return Dictionary::Ptr();
log_class = LogClassAlert;
log_type = LogTypeHostAlert;
@ -364,6 +373,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
plugin_output = tokens[4];
}
else if (boost::algorithm::contains(type, "HOST DOWNTIME ALERT")) {
if (tokens.size() < 3)
return Dictionary::Ptr();
log_class = LogClassAlert;
log_type = LogTypeHostDowntimeAlert;
@ -372,6 +384,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
comment = tokens[2];
}
else if (boost::algorithm::contains(type, "HOST FLAPPING ALERT")) {
if (tokens.size() < 3)
return Dictionary::Ptr();
log_class = LogClassAlert;
log_type = LogTypeHostFlapping;
@ -380,6 +395,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
comment = tokens[2];
}
else if (boost::algorithm::contains(type, "INITIAL SERVICE STATE")) {
if (tokens.size() < 6)
return Dictionary::Ptr();
log_class = LogClassState;
log_type = LogTypeServiceInitialState;
@ -391,6 +409,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
plugin_output = tokens[5];
}
else if (boost::algorithm::contains(type, "CURRENT SERVICE STATE")) {
if (tokens.size() < 6)
return Dictionary::Ptr();
log_class = LogClassState;
log_type = LogTypeServiceCurrentState;
@ -402,6 +423,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
plugin_output = tokens[5];
}
else if (boost::algorithm::contains(type, "SERVICE ALERT")) {
if (tokens.size() < 6)
return Dictionary::Ptr();
log_class = LogClassAlert;
log_type = LogTypeServiceAlert;
@ -413,6 +437,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
plugin_output = tokens[5];
}
else if (boost::algorithm::contains(type, "SERVICE DOWNTIME ALERT")) {
if (tokens.size() < 4)
return Dictionary::Ptr();
log_class = LogClassAlert;
log_type = LogTypeServiceDowntimeAlert;
@ -422,6 +449,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
comment = tokens[3];
}
else if (boost::algorithm::contains(type, "SERVICE FLAPPING ALERT")) {
if (tokens.size() < 4)
return Dictionary::Ptr();
log_class = LogClassAlert;
log_type = LogTypeServiceFlapping;
@ -431,6 +461,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
comment = tokens[3];
}
else if (boost::algorithm::contains(type, "TIMEPERIOD TRANSITION")) {
if (tokens.size() < 4)
return Dictionary::Ptr();
log_class = LogClassState;
log_type = LogTypeTimeperiodTransition;
@ -441,6 +474,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
}
/* Notifications - TODO refactor */
else if (boost::algorithm::contains(type, "HOST NOTIFICATION")) {
if (tokens.size() < 6)
return Dictionary::Ptr();
log_class = LogClassNotification;
log_type = LogTypeHostNotification;
@ -452,6 +488,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
plugin_output = tokens[5];
}
else if (boost::algorithm::contains(type, "SERVICE NOTIFICATION")) {
if (tokens.size() < 7)
return Dictionary::Ptr();
log_class = LogClassNotification;
log_type = LogTypeHostNotification;
@ -465,6 +504,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
}
/* Passive Checks - TODO refactor */
else if (boost::algorithm::contains(type, "PASSIVE HOST CHECK")) {
if (tokens.size() < 3)
return Dictionary::Ptr();
log_class = LogClassPassive;
host_name = tokens[0];
@ -472,6 +514,9 @@ Dictionary::Ptr LogTable::GetLogEntryAttributes(const String& type, const String
plugin_output = tokens[2];
}
else if (boost::algorithm::contains(type, "PASSIVE SERVICE CHECK")) {
if (tokens.size() < 4)
return Dictionary::Ptr();
log_class = LogClassPassive;
host_name = tokens[0];

View File

@ -59,6 +59,12 @@ Query::Query(const std::vector<String>& lines)
return;
}
String msg;
BOOST_FOREACH(const String& line, lines) {
msg += line + "\n";
}
Log(LogDebug, "livestatus", msg);
/* default separators */
m_Separators.push_back("\n");
m_Separators.push_back(";");
@ -253,8 +259,28 @@ int Query::GetExternalCommands(void)
Filter::Ptr Query::ParseFilter(const String& params, unsigned long& from, unsigned long& until)
{
/*
* time >= 1382696656
* type = SERVICE FLAPPING ALERT
*/
std::vector<String> tokens;
boost::algorithm::split(tokens, params, boost::is_any_of(" "));
size_t sp_index;
String temp_buffer = params;
/* extract attr and op */
for (int i = 0; i < 2; i++) {
sp_index = temp_buffer.FindFirstOf(" ");
/* 'attr op' or 'attr op val' is valid */
if (i < 1 && sp_index == String::NPos)
BOOST_THROW_EXCEPTION(std::runtime_error("Livestatus filter '" + params + "' does not contain all required fields."));
tokens.push_back(temp_buffer.SubStr(0, sp_index));
temp_buffer = temp_buffer.SubStr(sp_index + 1);
}
/* add the rest as value */
tokens.push_back(temp_buffer);
if (tokens.size() == 2)
tokens.push_back("");
@ -262,8 +288,10 @@ Filter::Ptr Query::ParseFilter(const String& params, unsigned long& from, unsign
if (tokens.size() < 3)
return Filter::Ptr();
String op = tokens[1];
bool negate = false;
String attr = tokens[0];
String op = tokens[1];
String val = tokens[2];
if (op == "!=") {
op = "=";
@ -279,19 +307,21 @@ Filter::Ptr Query::ParseFilter(const String& params, unsigned long& from, unsign
negate = true;
}
Filter::Ptr filter = boost::make_shared<AttributeFilter>(tokens[0], op, tokens[2]);
Filter::Ptr filter = boost::make_shared<AttributeFilter>(attr, op, val);
if (negate)
filter = boost::make_shared<NegateFilter>(filter);
/* pre-filter log time duration */
if (tokens[0] == "time") {
if (attr == "time") {
if (op == "<" || op == "<=") {
until = Convert::ToLong(tokens[2]);
until = Convert::ToLong(val);
} else if (op == ">" || op == ">=") {
from = Convert::ToLong(tokens[2]);
from = Convert::ToLong(val);
}
}
Log(LogDebug, "livestatus", "Parsed filter with attr: '" + attr + "' op: '" + op + "' val: '" + val + "'.");
return filter;
}
@ -371,7 +401,7 @@ void Query::ExecuteGetHelper(const Stream::Ptr& stream)
std::vector<Value> objects = table->FilterRows(m_Filter);
std::vector<String> columns;
if (m_Columns.size() > 0)
columns = m_Columns;
else
@ -399,7 +429,7 @@ void Query::ExecuteGetHelper(const Stream::Ptr& stream)
BOOST_FOREACH(const Value& object, objects) {
aggregator->Apply(table, object);
}
stats[index] = aggregator->GetResult();
index++;
}
@ -434,6 +464,7 @@ void Query::ExecuteCommandHelper(const Stream::Ptr& stream)
void Query::ExecuteErrorHelper(const Stream::Ptr& stream)
{
Log(LogDebug, "livestatus", "ERROR: Code: '" + Convert::ToString(m_ErrorCode) + "' Message: '" + m_ErrorMessage + "'.");
SendResponse(stream, m_ErrorCode, m_ErrorMessage);
}