Skip to content

IcingaDB: Make Redis & DB values consistent #10452

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 10, 2025
12 changes: 6 additions & 6 deletions lib/compat/compatlogger.cpp
Original file line number Diff line number Diff line change
@@ -130,7 +130,7 @@ void CompatLogger::CheckResultHandler(const Checkable::Ptr& checkable, const Che
<< host->GetName() << ";"
<< service->GetShortName() << ";"
<< Service::StateToString(service->GetState()) << ";"
<< Service::StateTypeToString(service->GetStateType()) << ";"
<< Checkable::StateTypeToString(service->GetStateType()) << ";"
<< attempt_after << ";"
<< output << ""
<< "";
@@ -140,7 +140,7 @@ void CompatLogger::CheckResultHandler(const Checkable::Ptr& checkable, const Che
msgbuf << "HOST ALERT: "
<< host->GetName() << ";"
<< GetHostStateString(host) << ";"
<< Host::StateTypeToString(host->GetStateType()) << ";"
<< Checkable::StateTypeToString(host->GetStateType()) << ";"
<< attempt_after << ";"
<< output << ""
<< "";
@@ -413,14 +413,14 @@ void CompatLogger::EventCommandHandler(const Checkable::Ptr& checkable)
<< host->GetName() << ";"
<< service->GetShortName() << ";"
<< Service::StateToString(service->GetState()) << ";"
<< Service::StateTypeToString(service->GetStateType()) << ";"
<< Checkable::StateTypeToString(service->GetStateType()) << ";"
<< current_attempt << ";"
<< event_command_name;
} else {
msgbuf << "HOST EVENT HANDLER: "
<< host->GetName() << ";"
<< GetHostStateString(host) << ";"
<< Host::StateTypeToString(host->GetStateType()) << ";"
<< Checkable::StateTypeToString(host->GetStateType()) << ";"
<< current_attempt << ";"
<< event_command_name;
}
@@ -505,7 +505,7 @@ void CompatLogger::ReopenFile(bool rotate)
msgbuf << "CURRENT HOST STATE: "
<< host->GetName() << ";"
<< GetHostStateString(host) << ";"
<< Host::StateTypeToString(host->GetStateType()) << ";"
<< Checkable::StateTypeToString(host->GetStateType()) << ";"
<< host->GetCheckAttempt() << ";"
<< output << "";

@@ -526,7 +526,7 @@ void CompatLogger::ReopenFile(bool rotate)
<< host->GetName() << ";"
<< service->GetShortName() << ";"
<< Service::StateToString(service->GetState()) << ";"
<< Service::StateTypeToString(service->GetStateType()) << ";"
<< Checkable::StateTypeToString(service->GetStateType()) << ";"
<< service->GetCheckAttempt() << ";"
<< output << "";

4 changes: 2 additions & 2 deletions lib/db_ido/dbevents.cpp
Original file line number Diff line number Diff line change
@@ -994,7 +994,7 @@ void DbEvents::AddCheckResultLogHistory(const Checkable::Ptr& checkable, const C
<< host->GetName() << ";"
<< service->GetShortName() << ";"
<< Service::StateToString(service->GetState()) << ";"
<< Service::StateTypeToString(service->GetStateType()) << ";"
<< Checkable::StateTypeToString(service->GetStateType()) << ";"
<< service->GetCheckAttempt() << ";"
<< output << ""
<< "";
@@ -1021,7 +1021,7 @@ void DbEvents::AddCheckResultLogHistory(const Checkable::Ptr& checkable, const C
msgbuf << "HOST ALERT: "
<< host->GetName() << ";"
<< GetHostStateString(host) << ";"
<< Host::StateTypeToString(host->GetStateType()) << ";"
<< Checkable::StateTypeToString(host->GetStateType()) << ";"
<< host->GetCheckAttempt() << ";"
<< output << ""
<< "";
6 changes: 6 additions & 0 deletions lib/icinga/checkable.cpp
Original file line number Diff line number Diff line change
@@ -322,3 +322,9 @@ void Checkable::CleanDeadlinedExecutions(const Timer * const&)
}
}
}

String Checkable::StateTypeToString(StateType type)
{
return type == StateTypeSoft ? "SOFT" : "HARD";
}

2 changes: 2 additions & 0 deletions lib/icinga/checkable.hpp
Original file line number Diff line number Diff line change
@@ -106,6 +106,8 @@ class Checkable : public ObjectImpl<Checkable>

void UpdateNextCheck(const MessageOrigin::Ptr& origin = nullptr);

static String StateTypeToString(StateType type);

bool HasBeenChecked() const;
virtual bool IsStateOK(ServiceState state) const = 0;

16 changes: 0 additions & 16 deletions lib/icinga/host.cpp
Original file line number Diff line number Diff line change
@@ -227,22 +227,6 @@ String Host::StateToString(HostState state)
}
}

StateType Host::StateTypeFromString(const String& type)
{
if (type == "SOFT")
return StateTypeSoft;
else
return StateTypeHard;
}

String Host::StateTypeToString(StateType type)
{
if (type == StateTypeSoft)
return "SOFT";
else
return "HARD";
}

bool Host::ResolveMacro(const String& macro, const CheckResult::Ptr&, Value *result) const
{
if (macro == "state") {
3 changes: 0 additions & 3 deletions lib/icinga/host.hpp
Original file line number Diff line number Diff line change
@@ -45,9 +45,6 @@ class Host final : public ObjectImpl<Host>, public MacroResolver
static HostState StateFromString(const String& state);
static String StateToString(HostState state);

static StateType StateTypeFromString(const String& state);
static String StateTypeToString(StateType state);

bool ResolveMacro(const String& macro, const CheckResult::Ptr& cr, Value *result) const override;

void OnAllConfigLoaded() override;
41 changes: 36 additions & 5 deletions lib/icinga/notification.cpp
Original file line number Diff line number Diff line change
@@ -100,12 +100,13 @@ void Notification::StaticInitialize()
m_TypeFilterMap["FlappingEnd"] = NotificationFlappingEnd;
}

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

SetTypeFilter(FilterArrayToInt(GetTypes(), GetTypeFilterMap(), ~0));
SetStateFilter(FilterArrayToInt(GetStates(), GetStateFilterMap(), ~0));
// If a notification is created without specifying the "types/states" attribute, the Set* methods won't be called,
// consequently the filter bitset will also be 0. Thus, we need to ensure that the type/state filter are
// initialized to the default values, which are all types and states enabled.
SetTypes(nullptr, false, Empty);
SetStates(nullptr, false, Empty);
}

void Notification::OnAllConfigLoaded()
@@ -751,6 +752,36 @@ String Notification::NotificationHostStateToString(HostState state)
}
}

Array::Ptr Notification::GetTypes() const
{
return m_Types.load();
}

void Notification::SetTypes(const Array::Ptr& value, bool suppress_events, const Value& cookie)
{
m_Types.store(value);
// Ensure that the type filter is updated when the types attribute changes.
SetTypeFilter(FilterArrayToInt(value, GetTypeFilterMap(), ~0));
if (!suppress_events) {
NotifyTypes(cookie);
}
}

Array::Ptr Notification::GetStates() const
{
return m_States.load();
}

void Notification::SetStates(const Array::Ptr& value, bool suppress_events, const Value& cookie)
{
m_States.store(value);
// Ensure that the state filter is updated when the states attribute changes.
SetStateFilter(FilterArrayToInt(value, GetStateFilterMap(), ~0));
if (!suppress_events) {
NotifyStates(cookie);
}
}

void Notification::Validate(int types, const ValidationUtils& utils)
{
ObjectImpl<Notification>::Validate(types, utils);
29 changes: 26 additions & 3 deletions lib/icinga/notification.hpp
Original file line number Diff line number Diff line change
@@ -29,7 +29,9 @@ enum NotificationFilter
StateFilterUnknown = 8,

StateFilterUp = 16,
StateFilterDown = 32
StateFilterDown = 32,

StateFilterAll = StateFilterOK | StateFilterWarning | StateFilterCritical | StateFilterUnknown | StateFilterUp | StateFilterDown,
};

/**
@@ -47,7 +49,11 @@ enum NotificationType
NotificationProblem = 32,
NotificationRecovery = 64,
NotificationFlappingStart = 128,
NotificationFlappingEnd = 256
NotificationFlappingEnd = 256,

NotificationTypeAll = NotificationDowntimeStart | NotificationDowntimeEnd | NotificationDowntimeRemoved |
NotificationCustom | NotificationAcknowledgement | NotificationProblem | NotificationRecovery |
NotificationFlappingStart | NotificationFlappingEnd,
};

class NotificationCommand;
@@ -68,6 +74,8 @@ class Notification final : public ObjectImpl<Notification>
DECLARE_OBJECT(Notification);
DECLARE_OBJECTNAME(Notification);

Notification();

static void StaticInitialize();

intrusive_ptr<Checkable> GetCheckable() const;
@@ -109,13 +117,28 @@ class Notification final : public ObjectImpl<Notification>
static const std::map<String, int>& GetStateFilterMap();
static const std::map<String, int>& GetTypeFilterMap();

void OnConfigLoaded() override;
void OnAllConfigLoaded() override;
void Start(bool runtimeCreated) override;
void Stop(bool runtimeRemoved) override;

Array::Ptr GetTypes() const override;
void SetTypes(const Array::Ptr& value, bool suppress_events, const Value& cookie) override;

Array::Ptr GetStates() const override;
void SetStates(const Array::Ptr& value, bool suppress_events, const Value& cookie) override;

private:
ObjectImpl<Checkable>::Ptr m_Checkable;
// These attributes represent the actual notification "types" and "states" attributes from the "notification.ti".
// However, since we want to ensure that the type and state bitsets are always in sync with those attributes,
// we need to override their setters, and this on the hand introduces another problem: The virtual setters are
// called from within the ObjectImpl<Notification> constructor, which obviously violates the C++ standard [^1].
// So, in order to avoid all this kind of mess, these two attributes have the "no_storage" flag set, and
// their getters/setters are pure virtual, which means this class has to provide the implementation of them.
//
// [^1]: https://isocpp.org/wiki/faq/strange-inheritance#calling-virtuals-from-ctors
AtomicOrLocked<Array::Ptr> m_Types;
AtomicOrLocked<Array::Ptr> m_States;

bool CheckNotificationUserFilters(NotificationType type, const User::Ptr& user, bool force, bool reminder);

10 changes: 8 additions & 2 deletions lib/icinga/notification.ti
Original file line number Diff line number Diff line change
@@ -41,9 +41,15 @@ class Notification : CustomVarObject < NotificationNameComposer
[config, signal_with_old_value] array(name(User)) users (UsersRaw);
[config, signal_with_old_value] array(name(UserGroup)) user_groups (UserGroupsRaw);
[config] Dictionary::Ptr times;
[config] array(Value) types;
[config, no_storage] array(Value) types {
get;
set;
};
[no_user_view, no_user_modify] int type_filter_real (TypeFilter);
[config] array(Value) states;
[config, no_storage] array(Value) states {
get;
set;
};
[no_user_view, no_user_modify] int state_filter_real (StateFilter);
[config, no_user_modify, protected, required, navigation(host)] name(Host) host_name {
navigate {{{
16 changes: 0 additions & 16 deletions lib/icinga/service.cpp
Original file line number Diff line number Diff line change
@@ -195,22 +195,6 @@ String Service::StateToString(ServiceState state)
}
}

StateType Service::StateTypeFromString(const String& type)
{
if (type == "SOFT")
return StateTypeSoft;
else
return StateTypeHard;
}

String Service::StateTypeToString(StateType type)
{
if (type == StateTypeSoft)
return "SOFT";
else
return "HARD";
}

bool Service::ResolveMacro(const String& macro, const CheckResult::Ptr& cr, Value *result) const
{
if (macro == "state") {
3 changes: 0 additions & 3 deletions lib/icinga/service.hpp
Original file line number Diff line number Diff line change
@@ -39,9 +39,6 @@ class Service final : public ObjectImpl<Service>, public MacroResolver
static ServiceState StateFromString(const String& state);
static String StateToString(ServiceState state);

static StateType StateTypeFromString(const String& state);
static String StateTypeToString(StateType state);

static void EvaluateApplyRules(const Host::Ptr& host);

void OnAllConfigLoaded() override;
41 changes: 36 additions & 5 deletions lib/icinga/user.cpp
Original file line number Diff line number Diff line change
@@ -12,12 +12,13 @@ using namespace icinga;

REGISTER_TYPE(User);

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

SetTypeFilter(FilterArrayToInt(GetTypes(), Notification::GetTypeFilterMap(), ~0));
SetStateFilter(FilterArrayToInt(GetStates(), Notification::GetStateFilterMap(), ~0));
// If a User is created without specifying the "types/states" attribute, the Set* methods won't be called,
// consequently the filter bitset will also be 0. Thus, we need to ensure that the type/state filter are
// initialized to the default values, which are all types and states enabled.
SetTypes(nullptr, false, Empty);
SetStates(nullptr, false, Empty);
}

void User::OnAllConfigLoaded()
@@ -80,6 +81,36 @@ TimePeriod::Ptr User::GetPeriod() const
return TimePeriod::GetByName(GetPeriodRaw());
}

Array::Ptr User::GetTypes() const
{
return m_Types.load();
}

void User::SetTypes(const Array::Ptr& value, bool suppress_events, const Value& cookie)
{
m_Types.store(value);
// Ensure that the type filter is updated when the types attribute changes.
SetTypeFilter(FilterArrayToInt(value, Notification::GetTypeFilterMap(), ~0));
if (!suppress_events) {
NotifyTypes(cookie);
}
}

Array::Ptr User::GetStates() const
{
return m_States.load();
}

void User::SetStates(const Array::Ptr& value, bool suppress_events, const Value& cookie)
{
m_States.store(value);
// Ensure that the state filter is updated when the states attribute changes.
SetStateFilter(FilterArrayToInt(value, Notification::GetStateFilterMap(), ~0));
if (!suppress_events) {
NotifyStates(cookie);
}
}

void User::ValidateStates(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils)
{
ObjectImpl<User>::ValidateStates(lvalue, utils);
19 changes: 18 additions & 1 deletion lib/icinga/user.hpp
Original file line number Diff line number Diff line change
@@ -22,21 +22,38 @@ class User final : public ObjectImpl<User>
DECLARE_OBJECT(User);
DECLARE_OBJECTNAME(User);

User();

void AddGroup(const String& name);

/* Notifications */
TimePeriod::Ptr GetPeriod() const;

Array::Ptr GetTypes() const override;
void SetTypes(const Array::Ptr& value, bool suppress_events, const Value& cookie) override;

Array::Ptr GetStates() const override;
void SetStates(const Array::Ptr& value, bool suppress_events, const Value& cookie) override;

void ValidateStates(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils) override;
void ValidateTypes(const Lazy<Array::Ptr>& lvalue, const ValidationUtils& utils) override;

protected:
void Stop(bool runtimeRemoved) override;

void OnConfigLoaded() override;
void OnAllConfigLoaded() override;
private:
mutable std::mutex m_UserMutex;
// These attributes represent the actual User "types" and "states" attributes from the "user.ti".
// However, since we want to ensure that the type and state bitsets are always in sync with those attributes,
// we need to override their setters, and this on the hand introduces another problem: The virtual setters are
// called from within the ObjectImpl<User> constructor, which obviously violates the C++ standard [^1].
// So, in order to avoid al this kind of mess, these two attributes have the "no_storage" flag set, and
// their getters/setters are pure virtual, which means this class has to provide the implementation of them.
//
// [^1]: https://isocpp.org/wiki/faq/strange-inheritance#calling-virtuals-from-ctors
AtomicOrLocked<Array::Ptr> m_Types;
AtomicOrLocked<Array::Ptr> m_States;
};

}
10 changes: 8 additions & 2 deletions lib/icinga/user.ti
Original file line number Diff line number Diff line change
@@ -29,9 +29,15 @@ class User : CustomVarObject
}}}
};

[config] array(Value) types;
[config, no_storage] array(Value) types {
get;
set;
};
[no_user_view, no_user_modify] int type_filter_real (TypeFilter);
[config] array(Value) states;
[config, no_storage] array(Value) states {
get;
set;
};
[no_user_view, no_user_modify] int state_filter_real (StateFilter);

[config] String email;
27 changes: 15 additions & 12 deletions lib/icingadb/icingadb-objects.cpp
Original file line number Diff line number Diff line change
@@ -1624,8 +1624,8 @@ bool IcingaDB::PrepareObject(const ConfigObject::Ptr& object, Dictionary::Ptr& a
attributes->Set("email", user->GetEmail());
attributes->Set("pager", user->GetPager());
attributes->Set("notifications_enabled", user->GetEnableNotifications());
attributes->Set("states", user->GetStates());
attributes->Set("types", user->GetTypes());
attributes->Set("states", StateFilterToRedisValue(user->GetStateFilter()));
attributes->Set("types", TypeFilterToRedisValue(user->GetTypeFilter()));

if (user->GetPeriod())
attributes->Set("timeperiod_id", GetObjectIdentifier(user->GetPeriod()));
@@ -1673,8 +1673,8 @@ bool IcingaDB::PrepareObject(const ConfigObject::Ptr& object, Dictionary::Ptr& a
}

attributes->Set("notification_interval", std::max(0.0, std::round(notification->GetInterval())));
attributes->Set("states", notification->GetStates());
attributes->Set("types", notification->GetTypes());
attributes->Set("states", StateFilterToRedisValue(notification->GetStateFilter()));
attributes->Set("types", TypeFilterToRedisValue(notification->GetTypeFilter()));

return true;
}
@@ -1684,7 +1684,7 @@ bool IcingaDB::PrepareObject(const ConfigObject::Ptr& object, Dictionary::Ptr& a

attributes->Set("author", comment->GetAuthor());
attributes->Set("text", comment->GetText());
attributes->Set("entry_type", comment->GetEntryType());
attributes->Set("entry_type", IcingaDB::CommentTypeToString(comment->GetEntryType()));
attributes->Set("entry_time", TimestampToMilliseconds(comment->GetEntryTime()));
attributes->Set("is_persistent", comment->GetPersistent());
attributes->Set("is_sticky", comment->GetSticky());
@@ -1974,7 +1974,7 @@ void IcingaDB::SendStateChange(const ConfigObject::Ptr& object, const CheckResul
"id", HashValue(rawId),
"environment_id", m_EnvironmentId,
"host_id", GetObjectIdentifier(host),
"state_type", Convert::ToString(type),
"state_type", Checkable::StateTypeToString(type).ToLower(),
"soft_state", Convert::ToString(cr ? service ? Convert::ToLong(cr->GetState()) : Convert::ToLong(Host::CalculateState(cr->GetState())) : 99),
"hard_state", Convert::ToString(hard_state),
"check_attempt", Convert::ToString(checkable->GetCheckAttempt()),
@@ -2047,8 +2047,9 @@ void IcingaDB::SendSentNotification(
auto usersAmount (users.size());
auto sendTs (TimestampToMilliseconds(sendTime));

auto notificationTypeStr(GetNotificationTypeByEnum(type));
Array::Ptr rawId = new Array({m_EnvironmentId, notification->GetName()});
rawId->Add(GetNotificationTypeByEnum(type));
rawId->Add(notificationTypeStr);
rawId->Add(sendTs);

auto notificationHistoryId (HashValue(rawId));
@@ -2059,7 +2060,7 @@ void IcingaDB::SendSentNotification(
"environment_id", m_EnvironmentId,
"notification_id", GetObjectIdentifier(notification),
"host_id", GetObjectIdentifier(host),
"type", Convert::ToString(type),
"type", notificationTypeStr,
"state", Convert::ToString(cr ? service ? Convert::ToLong(cr->GetState()) : Convert::ToLong(Host::CalculateState(cr->GetState())) : 99),
"previous_hard_state", Convert::ToString(cr ? service ? Convert::ToLong(cr->GetPreviousHardState()) : Convert::ToLong(Host::CalculateState(cr->GetPreviousHardState())) : 99),
"author", Utility::ValidateUTF8(author),
@@ -2300,7 +2301,7 @@ void IcingaDB::SendAddedComment(const Comment::Ptr& comment)
"entry_time", Convert::ToString(TimestampToMilliseconds(comment->GetEntryTime())),
"author", Utility::ValidateUTF8(comment->GetAuthor()),
"comment", Utility::ValidateUTF8(comment->GetText()),
"entry_type", Convert::ToString(comment->GetEntryType()),
"entry_type", IcingaDB::CommentTypeToString(comment->GetEntryType()),
"is_persistent", Convert::ToString((unsigned short)comment->GetPersistent()),
"is_sticky", Convert::ToString((unsigned short)comment->GetSticky()),
"event_id", CalcEventID("comment_add", comment),
@@ -2372,7 +2373,7 @@ void IcingaDB::SendRemovedComment(const Comment::Ptr& comment)
"entry_time", Convert::ToString(TimestampToMilliseconds(comment->GetEntryTime())),
"author", Utility::ValidateUTF8(comment->GetAuthor()),
"comment", Utility::ValidateUTF8(comment->GetText()),
"entry_type", Convert::ToString(comment->GetEntryType()),
"entry_type", IcingaDB::CommentTypeToString(comment->GetEntryType()),
"is_persistent", Convert::ToString((unsigned short)comment->GetPersistent()),
"is_sticky", Convert::ToString((unsigned short)comment->GetSticky()),
"event_id", CalcEventID("comment_remove", comment),
@@ -2954,7 +2955,7 @@ Dictionary::Ptr IcingaDB::SerializeState(const Checkable::Ptr& checkable)
*/
attrs->Set("id", id);
attrs->Set("environment_id", m_EnvironmentId);
attrs->Set("state_type", checkable->HasBeenChecked() ? checkable->GetStateType() : StateTypeHard);
attrs->Set("state_type", Checkable::StateTypeToString(checkable->HasBeenChecked() ? checkable->GetStateType() : StateTypeHard).ToLower());

// TODO: last_hard/soft_state should be "previous".
if (service) {
@@ -3017,7 +3018,9 @@ Dictionary::Ptr IcingaDB::SerializeState(const Checkable::Ptr& checkable)
attrs->Set("is_reachable", checkable->IsReachable());
attrs->Set("is_flapping", checkable->IsFlapping());

attrs->Set("is_acknowledged", checkable->GetAcknowledgement());
attrs->Set("is_acknowledged", checkable->IsAcknowledged());
attrs->Set("is_sticky_acknowledgement", checkable->GetAcknowledgement() == AcknowledgementSticky);

if (checkable->IsAcknowledged()) {
Timestamp entry = 0;
Comment::Ptr AckComment;
46 changes: 45 additions & 1 deletion lib/icingadb/icingadb-utility.cpp
Original file line number Diff line number Diff line change
@@ -219,6 +219,35 @@ Dictionary::Ptr IcingaDB::SerializeRedundancyGroupState(const Checkable::Ptr& ch
};
}

/**
* Converts the given filter to its Redis value representation.
*
* Within the Icinga 2 code base, if the states filter bitsets are set to -1, the filter will match on all states.
* However, since sending -1 to Redis would crash the Icinga DB daemon, as the "states" field is of type uint8, so
* the primary purpose of this function is to make sure that no values outside the valid range of 0-255 are sent to Redis.
*
* @param filter The filter to convert.
*/
int IcingaDB::StateFilterToRedisValue(int filter)
{
return filter & StateFilterAll;
}

/**
* Converts the given filter to its Redis value representation.
*
* Within the Icinga 2 code base, if the types filter bitsets are set to -1, the filter will match on all types.
* However, since sending -1 to Redis would crash the Icinga DB daemon, as the "types" field is of type uint16, so
* the primary purpose of this function is to make sure that no values outside the "types" field's valid range are
* sent to Redis.
*
* @param filter The filter to convert.
*/
int IcingaDB::TypeFilterToRedisValue(int filter)
{
return filter & NotificationTypeAll;
}

const char* IcingaDB::GetNotificationTypeByEnum(NotificationType type)
{
switch (type) {
@@ -240,9 +269,24 @@ const char* IcingaDB::GetNotificationTypeByEnum(NotificationType type)
return "flapping_start";
case NotificationFlappingEnd:
return "flapping_end";
default:
VERIFY(!"Invalid notification type.");
}
}

VERIFY(!"Invalid notification type.");
/**
* Converts the given comment type to its string representation.
*
* @ingroup icinga
*/
String IcingaDB::CommentTypeToString(CommentType type)
{
switch (type) {
case CommentUser: return "comment";
case CommentAcknowledgement: return "ack";
default:
BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid comment type specified"));
}
}

static const std::set<String> propertiesBlacklistEmpty;
3 changes: 3 additions & 0 deletions lib/icingadb/icingadb.hpp
Original file line number Diff line number Diff line change
@@ -173,7 +173,10 @@ class IcingaDB : public ObjectImpl<IcingaDB>

static String GetObjectIdentifier(const ConfigObject::Ptr& object);
static String CalcEventID(const char* eventType, const ConfigObject::Ptr& object, double eventTime = 0, NotificationType nt = NotificationType(0));
static int StateFilterToRedisValue(int filter);
static int TypeFilterToRedisValue(int filter);
static const char* GetNotificationTypeByEnum(NotificationType type);
static String CommentTypeToString(CommentType type);
static Dictionary::Ptr SerializeVars(const Dictionary::Ptr& vars);
static Dictionary::Ptr SerializeDependencyEdgeState(const DependencyGroup::Ptr& dependencyGroup, const Dependency::Ptr& dep);
static Dictionary::Ptr SerializeRedundancyGroupState(const Checkable::Ptr& child, const DependencyGroup::Ptr& redundancyGroup);