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

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
12 changes: 6 additions & 6 deletions lib/compat/compatlogger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 << ""
<< "";
Expand All @@ -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 << ""
<< "";
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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 << "";

Expand All @@ -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 << "";

Expand Down
4 changes: 2 additions & 2 deletions lib/db_ido/dbevents.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 << ""
<< "";
Expand All @@ -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 << ""
<< "";
Expand Down
6 changes: 6 additions & 0 deletions lib/icinga/checkable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Up @@ -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;

Expand Down
16 changes: 0 additions & 16 deletions lib/icinga/host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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") {
Expand Down
3 changes: 0 additions & 3 deletions lib/icinga/host.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
41 changes: 36 additions & 5 deletions lib/icinga/notification.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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, Value());
SetStates(nullptr, false, Value());
}

void Notification::OnAllConfigLoaded()
Expand Down Expand Up @@ -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);
Expand Down
29 changes: 26 additions & 3 deletions lib/icinga/notification.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ enum NotificationFilter
StateFilterUnknown = 8,

StateFilterUp = 16,
StateFilterDown = 32
StateFilterDown = 32,

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

/**
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);

Expand Down
10 changes: 8 additions & 2 deletions lib/icinga/notification.ti
Original file line number Diff line number Diff line change
Expand Up @@ -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 {{{
Expand Down
16 changes: 0 additions & 16 deletions lib/icinga/service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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") {
Expand Down
3 changes: 0 additions & 3 deletions lib/icinga/service.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
41 changes: 36 additions & 5 deletions lib/icinga/user.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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, Value());
SetStates(nullptr, false, Value());
}

void User::OnAllConfigLoaded()
Expand Down Expand Up @@ -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);
Expand Down
19 changes: 18 additions & 1 deletion lib/icinga/user.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 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 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;
};

}
Expand Down
Loading
Loading