Skip to content

Commit

Permalink
WIP: Allow strings in state and type filters (config, API)
Browse files Browse the repository at this point in the history
refs #11445
  • Loading branch information
Michael Friedrich committed Jun 21, 2016
1 parent e3f1c1e commit 86699ec
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 61 deletions.
12 changes: 6 additions & 6 deletions lib/db_ido/userdbobject.cpp
Expand Up @@ -53,16 +53,16 @@ Dictionary::Ptr UserDbObject::GetConfigFields(void) const
int typeFilter = user->GetTypeFilter();
int stateFilter = user->GetStateFilter();

fields->Set("notify_service_recovery", (typeFilter & (1 << NotificationRecovery)) != 0);
fields->Set("notify_service_recovery", (typeFilter & NotificationRecovery) != 0);
fields->Set("notify_service_warning", (stateFilter & StateFilterWarning) != 0);
fields->Set("notify_service_unknown", (stateFilter & StateFilterUnknown) != 0);
fields->Set("notify_service_critical", (stateFilter & StateFilterCritical) != 0);
fields->Set("notify_service_flapping", (typeFilter & ((1 << NotificationFlappingStart) | (1 << NotificationFlappingEnd))) != 0);
fields->Set("notify_service_downtime", (typeFilter & ((1 << NotificationDowntimeStart) | (1 << NotificationDowntimeEnd) | (1 << NotificationDowntimeRemoved))) != 0);
fields->Set("notify_host_recovery", (typeFilter & (1 << NotificationRecovery)) != 0);
fields->Set("notify_service_flapping", (typeFilter & (NotificationFlappingStart | NotificationFlappingEnd)) != 0);
fields->Set("notify_service_downtime", (typeFilter & (NotificationDowntimeStart | NotificationDowntimeEnd | NotificationDowntimeRemoved)) != 0);
fields->Set("notify_host_recovery", (typeFilter & NotificationRecovery) != 0);
fields->Set("notify_host_down", (stateFilter & StateFilterDown) != 0);
fields->Set("notify_host_flapping", (typeFilter & ((1 << NotificationFlappingStart) | (1 << NotificationFlappingEnd))) != 0);
fields->Set("notify_host_downtime", (typeFilter & ((1 << NotificationDowntimeStart) | (1 << NotificationDowntimeEnd) | (1 << NotificationDowntimeRemoved))) != 0);
fields->Set("notify_host_flapping", (typeFilter & (NotificationFlappingStart | NotificationFlappingEnd)) != 0);
fields->Set("notify_host_downtime", (typeFilter & (NotificationDowntimeStart | NotificationDowntimeEnd | NotificationDowntimeRemoved)) != 0);

return fields;
}
Expand Down
4 changes: 2 additions & 2 deletions lib/icinga/dependency.cpp
Expand Up @@ -77,7 +77,7 @@ void Dependency::OnConfigLoaded(void)
else
defaultFilter = StateFilterOK | StateFilterWarning;

SetStateFilter(FilterArrayToInt(GetStates(), defaultFilter));
SetStateFilter(FilterArrayToInt(GetStates(), Notification::GetStateFilterMap(), defaultFilter));
}

void Dependency::OnAllConfigLoaded(void)
Expand Down Expand Up @@ -224,7 +224,7 @@ void Dependency::ValidateStates(const Array::Ptr& value, const ValidationUtils&
{
ObjectImpl<Dependency>::ValidateStates(value, utils);

int sfilter = FilterArrayToInt(value, 0);
int sfilter = FilterArrayToInt(value, Notification::GetStateFilterMap(), 0);

if (GetParentServiceName().IsEmpty() && (sfilter & ~(StateFilterUp | StateFilterDown)) != 0)
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("states"), "State filter is invalid for host dependency."));
Expand Down
102 changes: 73 additions & 29 deletions lib/icinga/notification.cpp
Expand Up @@ -37,6 +37,9 @@ using namespace icinga;
REGISTER_TYPE(Notification);
INITIALIZE_ONCE(&Notification::StaticInitialize);

std::map<String, int> Notification::m_StateFilterMap;
std::map<String, int> Notification::m_TypeFilterMap;

boost::signals2::signal<void (const Notification::Ptr&, const MessageOrigin::Ptr&)> Notification::OnNextNotificationChanged;

String NotificationNameComposer::MakeName(const String& shortName, const Object::Ptr& context) const
Expand Down Expand Up @@ -79,30 +82,47 @@ Dictionary::Ptr NotificationNameComposer::ParseName(const String& name) const

void Notification::StaticInitialize(void)
{
ScriptGlobal::Set("OK", StateFilterOK);
ScriptGlobal::Set("Warning", StateFilterWarning);
ScriptGlobal::Set("Critical", StateFilterCritical);
ScriptGlobal::Set("Unknown", StateFilterUnknown);
ScriptGlobal::Set("Up", StateFilterUp);
ScriptGlobal::Set("Down", StateFilterDown);

ScriptGlobal::Set("DowntimeStart", 1 << NotificationDowntimeStart);
ScriptGlobal::Set("DowntimeEnd", 1 << NotificationDowntimeEnd);
ScriptGlobal::Set("DowntimeRemoved", 1 << NotificationDowntimeRemoved);
ScriptGlobal::Set("Custom", 1 << NotificationCustom);
ScriptGlobal::Set("Acknowledgement", 1 << NotificationAcknowledgement);
ScriptGlobal::Set("Problem", 1 << NotificationProblem);
ScriptGlobal::Set("Recovery", 1 << NotificationRecovery);
ScriptGlobal::Set("FlappingStart", 1 << NotificationFlappingStart);
ScriptGlobal::Set("FlappingEnd", 1 << NotificationFlappingEnd);
ScriptGlobal::Set("OK", "OK");
ScriptGlobal::Set("Warning", "Warning");
ScriptGlobal::Set("Critical", "Critical");
ScriptGlobal::Set("Unknown", "Unknown");
ScriptGlobal::Set("Up", "Up");
ScriptGlobal::Set("Down", "Down");

ScriptGlobal::Set("DowntimeStart", "DowntimeStart");
ScriptGlobal::Set("DowntimeEnd", "DowntimeEnd");
ScriptGlobal::Set("DowntimeRemoved", "DowntimeRemoved");
ScriptGlobal::Set("Custom", "Custom");
ScriptGlobal::Set("Acknowledgement", "Acknowledgement");
ScriptGlobal::Set("Problem", "Problem");
ScriptGlobal::Set("Recovery", "Recovery");
ScriptGlobal::Set("FlappingStart", "FlappingStart");
ScriptGlobal::Set("FlappingEnd", "FlappingEnd");

m_StateFilterMap["OK"] = StateFilterOK;
m_StateFilterMap["Warning"] = StateFilterWarning;
m_StateFilterMap["Critical"] = StateFilterCritical;
m_StateFilterMap["Unknown"] = StateFilterUnknown;
m_StateFilterMap["Up"] = StateFilterUp;
m_StateFilterMap["Down"] = StateFilterDown;

m_TypeFilterMap["DowntimeStart"] = NotificationDowntimeStart;
m_TypeFilterMap["DowntimeEnd"] = NotificationDowntimeEnd;
m_TypeFilterMap["DowntimeRemoved"] = NotificationDowntimeRemoved;
m_TypeFilterMap["Custom"] = NotificationCustom;
m_TypeFilterMap["Acknowledgement"] = NotificationAcknowledgement;
m_TypeFilterMap["Problem"] = NotificationProblem;
m_TypeFilterMap["Recovery"] = NotificationRecovery;
m_TypeFilterMap["FlappingStart"] = NotificationFlappingStart;
m_TypeFilterMap["FlappingEnd"] = NotificationFlappingEnd;
}

void Notification::OnConfigLoaded(void)
{
ObjectImpl<Notification>::OnConfigLoaded();

SetTypeFilter(FilterArrayToInt(GetTypes(), ~0));
SetStateFilter(FilterArrayToInt(GetStates(), ~0));
SetTypeFilter(FilterArrayToInt(GetTypes(), GetTypeFilterMap(), ~0));
SetStateFilter(FilterArrayToInt(GetStates(), GetStateFilterMap(), ~0));
}

void Notification::OnAllConfigLoaded(void)
Expand Down Expand Up @@ -280,7 +300,7 @@ void Notification::BeginExecuteNotification(NotificationType type, const CheckRe
}
}

unsigned long ftype = 1 << type;
unsigned long ftype = type;

Log(LogDebug, "Notification")
<< "Type '" << NotificationTypeToStringInternal(type)
Expand Down Expand Up @@ -412,7 +432,7 @@ bool Notification::CheckNotificationUserFilters(NotificationType type, const Use
return false;
}

unsigned long ftype = 1 << type;
unsigned long ftype = type;

Log(LogDebug, "Notification")
<< "User notification, Type '" << NotificationTypeToStringInternal(type)
Expand Down Expand Up @@ -520,7 +540,7 @@ int icinga::HostStateToFilter(HostState state)
}
}

int icinga::FilterArrayToInt(const Array::Ptr& typeFilters, int defaultValue)
int icinga::FilterArrayToInt(const Array::Ptr& typeFilters, const std::map<String, int>& filterMap, int defaultValue)
{
Value resultTypeFilter;

Expand All @@ -531,7 +551,20 @@ int icinga::FilterArrayToInt(const Array::Ptr& typeFilters, int defaultValue)

ObjectLock olock(typeFilters);
BOOST_FOREACH(const Value& typeFilter, typeFilters) {
resultTypeFilter = resultTypeFilter | typeFilter;
if (typeFilter.IsNumber()) {
resultTypeFilter = resultTypeFilter | typeFilter;
continue;
}

if (!typeFilter.IsString())
return -1;

std::map<String, int>::const_iterator it = filterMap.find(typeFilter);

if (it == filterMap.end())
return -1;

resultTypeFilter = resultTypeFilter | it->second;
}

return resultTypeFilter;
Expand All @@ -545,6 +578,8 @@ std::vector<String> icinga::FilterIntToArray(int iFilter)
filter.push_back("OK");
if (iFilter & StateFilterWarning)
filter.push_back("Warning");
if (iFilter & StateFilterCritical)
filter.push_back("Critical");
if (iFilter & StateFilterUnknown)
filter.push_back("Unknown");
if (iFilter & StateFilterUp)
Expand Down Expand Up @@ -651,24 +686,24 @@ void Notification::ValidateStates(const Array::Ptr& value, const ValidationUtils
{
ObjectImpl<Notification>::ValidateStates(value, utils);

int sfilter = FilterArrayToInt(value, 0);
int filter = FilterArrayToInt(value, GetStateFilterMap(), 0);

if (GetServiceName().IsEmpty() && (sfilter & ~(StateFilterUp | StateFilterDown)) != 0)
if (GetServiceName().IsEmpty() && (filter == -1 || (filter & ~(StateFilterUp | StateFilterDown)) != 0))
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("states"), "State filter is invalid."));

if (!GetServiceName().IsEmpty() && (sfilter & ~(StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0)
if (!GetServiceName().IsEmpty() && (filter == -1 || (filter & ~(StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0))
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("types"), "State filter is invalid."));
}

void Notification::ValidateTypes(const Array::Ptr& value, const ValidationUtils& utils)
{
ObjectImpl<Notification>::ValidateTypes(value, utils);

int tfilter = FilterArrayToInt(value, 0);
int filter = FilterArrayToInt(value, GetTypeFilterMap(), 0);

if ((tfilter & ~(1 << NotificationDowntimeStart | 1 << NotificationDowntimeEnd | 1 << NotificationDowntimeRemoved |
1 << NotificationCustom | 1 << NotificationAcknowledgement | 1 << NotificationProblem | 1 << NotificationRecovery |
1 << NotificationFlappingStart | 1 << NotificationFlappingEnd)) != 0)
if (filter == -1 || (filter & ~(NotificationDowntimeStart | NotificationDowntimeEnd | NotificationDowntimeRemoved |
NotificationCustom | NotificationAcknowledgement | NotificationProblem | NotificationRecovery |
NotificationFlappingStart | NotificationFlappingEnd)) != 0)
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("types"), "Type filter is invalid."));
}

Expand All @@ -677,3 +712,12 @@ Endpoint::Ptr Notification::GetCommandEndpoint(void) const
return Endpoint::GetByName(GetCommandEndpointRaw());
}

const std::map<String, int>& Notification::GetStateFilterMap(void)
{
return m_StateFilterMap;
}

const std::map<String, int>& Notification::GetTypeFilterMap(void)
{
return m_TypeFilterMap;
}
26 changes: 16 additions & 10 deletions lib/icinga/notification.hpp
Expand Up @@ -55,15 +55,15 @@ enum NotificationFilter
*/
enum NotificationType
{
NotificationDowntimeStart = 0,
NotificationDowntimeEnd = 1,
NotificationDowntimeRemoved = 2,
NotificationCustom = 3,
NotificationAcknowledgement = 4,
NotificationProblem = 5,
NotificationRecovery = 6,
NotificationFlappingStart = 7 ,
NotificationFlappingEnd = 8,
NotificationDowntimeStart = 1,
NotificationDowntimeEnd = 2,
NotificationDowntimeRemoved = 4,
NotificationCustom = 8,
NotificationAcknowledgement = 16,
NotificationProblem = 32,
NotificationRecovery = 64,
NotificationFlappingStart = 128,
NotificationFlappingEnd = 256
};

class NotificationCommand;
Expand Down Expand Up @@ -115,6 +115,9 @@ class I2_ICINGA_API Notification : public ObjectImpl<Notification>
static void EvaluateApplyRules(const intrusive_ptr<Host>& host);
static void EvaluateApplyRules(const intrusive_ptr<Service>& service);

static const std::map<String, int>& GetStateFilterMap(void);
static const std::map<String, int>& GetTypeFilterMap(void);

protected:
virtual void OnConfigLoaded(void) override;
virtual void OnAllConfigLoaded(void) override;
Expand All @@ -132,11 +135,14 @@ class I2_ICINGA_API Notification : public ObjectImpl<Notification>
static String NotificationTypeToStringInternal(NotificationType type);
static String NotificationServiceStateToString(ServiceState state);
static String NotificationHostStateToString(HostState state);

static std::map<String, int> m_StateFilterMap;
static std::map<String, int> m_TypeFilterMap;
};

I2_ICINGA_API int ServiceStateToFilter(ServiceState state);
I2_ICINGA_API int HostStateToFilter(HostState state);
I2_ICINGA_API int FilterArrayToInt(const Array::Ptr& typeFilters, int defaultValue);
I2_ICINGA_API int FilterArrayToInt(const Array::Ptr& typeFilters, const std::map<String, int>& filterMap, int defaultValue);
I2_ICINGA_API std::vector<String> FilterIntToArray(int iFilter);

}
Expand Down
4 changes: 2 additions & 2 deletions lib/icinga/notification.ti
Expand Up @@ -56,9 +56,9 @@ class Notification : CustomVarObject < NotificationNameComposer
[config, protected] array(name(User)) users (UsersRaw);
[config, protected] array(name(UserGroup)) user_groups (UserGroupsRaw);
[config] Dictionary::Ptr times;
[config] array(double) types;
[config] array(Value) types;
int type_filter_real (TypeFilter);
[config] array(double) states;
[config] array(Value) states;
int state_filter_real (StateFilter);
[config, protected, required, navigation(host)] name(Host) host_name {
navigate {{{
Expand Down
18 changes: 8 additions & 10 deletions lib/icinga/user.cpp
Expand Up @@ -34,8 +34,8 @@ void User::OnConfigLoaded(void)
{
ObjectImpl<User>::OnConfigLoaded();

SetTypeFilter(FilterArrayToInt(GetTypes(), ~0));
SetStateFilter(FilterArrayToInt(GetStates(), ~0));
SetTypeFilter(FilterArrayToInt(GetTypes(), Notification::GetTypeFilterMap(), ~0));
SetStateFilter(FilterArrayToInt(GetStates(), Notification::GetStateFilterMap(), ~0));
}

void User::OnAllConfigLoaded(void)
Expand Down Expand Up @@ -102,22 +102,20 @@ void User::ValidateStates(const Array::Ptr& value, const ValidationUtils& utils)
{
ObjectImpl<User>::ValidateStates(value, utils);

int sfilter = FilterArrayToInt(value, 0);
int filter = FilterArrayToInt(value, Notification::GetStateFilterMap(), 0);

if ((sfilter & ~(StateFilterUp | StateFilterDown | StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0) {
if (filter == -1 || (filter & ~(StateFilterUp | StateFilterDown | StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown)) != 0)
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("states"), "State filter is invalid."));
}
}

void User::ValidateTypes(const Array::Ptr& value, const ValidationUtils& utils)
{
ObjectImpl<User>::ValidateTypes(value, utils);

int tfilter = FilterArrayToInt(value, 0);
int filter = FilterArrayToInt(value, Notification::GetTypeFilterMap(), 0);

if ((tfilter & ~(1 << NotificationDowntimeStart | 1 << NotificationDowntimeEnd | 1 << NotificationDowntimeRemoved |
1 << NotificationCustom | 1 << NotificationAcknowledgement | 1 << NotificationProblem | 1 << NotificationRecovery |
1 << NotificationFlappingStart | 1 << NotificationFlappingEnd)) != 0) {
if (filter == -1 || (filter & ~(NotificationDowntimeStart | NotificationDowntimeEnd | NotificationDowntimeRemoved |
NotificationCustom | NotificationAcknowledgement | NotificationProblem | NotificationRecovery |
NotificationFlappingStart | NotificationFlappingEnd)) != 0)
BOOST_THROW_EXCEPTION(ValidationError(this, boost::assign::list_of("types"), "Type filter is invalid."));
}
}
4 changes: 2 additions & 2 deletions lib/icinga/user.ti
Expand Up @@ -44,9 +44,9 @@ class User : CustomVarObject
}}}
};

[config] array(double) types;
[config] array(Value) types;
int type_filter_real (TypeFilter);
[config] array(double) states;
[config] array(Value) states;
int state_filter_real (StateFilter);

[config] String email;
Expand Down

0 comments on commit 86699ec

Please sign in to comment.