Skip to content

Commit

Permalink
/v1/actions/schedule-downtime: reject request on invalid trigger_name
Browse files Browse the repository at this point in the history
For this purpose lookup the specified Downtime. Also pass Downtime objects,
not just names, to Downtime::AddDowntime() not to lookup it twice.
  • Loading branch information
Al2Klimov committed Sep 17, 2024
1 parent a3dd32e commit 58a10ad
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 72 deletions.
26 changes: 17 additions & 9 deletions lib/icinga/apiactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -391,9 +391,16 @@ Dictionary::Ptr ApiActions::ScheduleDowntime(const ConfigObject::Ptr& object,
if (params->Contains("duration"))
duration = HttpUtility::GetLastParameter(params, "duration");

String triggerName;
if (params->Contains("trigger_name"))
triggerName = HttpUtility::GetLastParameter(params, "trigger_name");
Downtime::Ptr trigger;
String triggerName = HttpUtility::GetLastParameter(params, "trigger_name");

if (!triggerName.IsEmpty()) {
trigger = Downtime::GetByName(triggerName);

if (!trigger) {
return ApiActions::CreateResult(404, "Won't schedule downtime with non-existent trigger downtime.");
}
}

String author = HttpUtility::GetLastParameter(params, "author");
String comment = HttpUtility::GetLastParameter(params, "comment");
Expand All @@ -420,7 +427,7 @@ Dictionary::Ptr ApiActions::ScheduleDowntime(const ConfigObject::Ptr& object,
}

Downtime::Ptr downtime = Downtime::AddDowntime(checkable, author, comment, startTime, endTime,
fixed, triggerName, duration);
fixed, trigger, duration);
String downtimeName = downtime->GetName();

Dictionary::Ptr additional = new Dictionary({
Expand All @@ -442,7 +449,7 @@ Dictionary::Ptr ApiActions::ScheduleDowntime(const ConfigObject::Ptr& object,
<< "Creating downtime for service " << hostService->GetName() << " on host " << host->GetName();

Downtime::Ptr serviceDowntime = Downtime::AddDowntime(hostService, author, comment, startTime, endTime,
fixed, triggerName, duration, String(), String(), downtimeName);
fixed, trigger, duration, String(), String(), downtimeName);
String serviceDowntimeName = serviceDowntime->GetName();

serviceDowntimes.push_back(new Dictionary({
Expand All @@ -459,8 +466,9 @@ Dictionary::Ptr ApiActions::ScheduleDowntime(const ConfigObject::Ptr& object,
/* 'DowntimeTriggeredChildren' schedules child downtimes triggered by the parent downtime.
* 'DowntimeNonTriggeredChildren' schedules non-triggered downtimes for all children.
*/
if (childOptions == DowntimeTriggeredChildren)
triggerName = downtimeName;
if (childOptions == DowntimeTriggeredChildren) {
trigger = downtime;
}

Log(LogNotice, "ApiActions")
<< "Processing child options " << childOptions << " for downtime " << downtimeName;
Expand All @@ -486,7 +494,7 @@ Dictionary::Ptr ApiActions::ScheduleDowntime(const ConfigObject::Ptr& object,
<< "Scheduling downtime for child object " << child->GetName();

Downtime::Ptr childDowntime = Downtime::AddDowntime(child, author, comment, startTime, endTime,
fixed, triggerName, duration);
fixed, trigger, duration);
String childDowntimeName = childDowntime->GetName();

Log(LogNotice, "ApiActions")
Expand All @@ -506,7 +514,7 @@ Dictionary::Ptr ApiActions::ScheduleDowntime(const ConfigObject::Ptr& object,
<< "Creating downtime for service " << childService->GetName() << " on child host " << childHost->GetName();

Downtime::Ptr serviceDowntime = Downtime::AddDowntime(childService, author, comment, startTime, endTime,
fixed, triggerName, duration, String(), String(), childDowntimeName);
fixed, trigger, duration, String(), String(), childDowntimeName);
String serviceDowntimeName = serviceDowntime->GetName();

childServiceDowntimes.push_back(new Dictionary({
Expand Down
10 changes: 7 additions & 3 deletions lib/icinga/downtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,17 +245,22 @@ int Downtime::GetNextDowntimeID()

Downtime::Ptr Downtime::AddDowntime(const Checkable::Ptr& checkable, const String& author,
const String& comment, double startTime, double endTime, bool fixed,
const String& triggeredBy, double duration,
const Downtime::Ptr& parentDowntime, double duration,
const String& scheduledDowntime, const String& scheduledBy, const String& parent,
const String& id, const MessageOrigin::Ptr& origin)
{
String fullName;
String triggeredBy;

if (id.IsEmpty())
fullName = checkable->GetName() + "!" + Utility::NewUniqueID();
else
fullName = id;

if (parentDowntime) {
triggeredBy = parentDowntime->GetName();
}

Dictionary::Ptr attrs = new Dictionary();

attrs->Set("author", author);
Expand Down Expand Up @@ -326,8 +331,7 @@ Downtime::Ptr Downtime::AddDowntime(const Checkable::Ptr& checkable, const Strin
BOOST_THROW_EXCEPTION(std::runtime_error("Could not create downtime."));
}

if (!triggeredBy.IsEmpty()) {
Downtime::Ptr parentDowntime = Downtime::GetByName(triggeredBy);
if (parentDowntime) {
Array::Ptr triggers = parentDowntime->GetTriggers();

ObjectLock olock(triggers);
Expand Down
2 changes: 1 addition & 1 deletion lib/icinga/downtime.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class Downtime final : public ObjectImpl<Downtime>

static Ptr AddDowntime(const intrusive_ptr<Checkable>& checkable, const String& author,
const String& comment, double startTime, double endTime, bool fixed,
const String& triggeredBy, double duration, const String& scheduledDowntime = String(),
const Ptr& parentDowntime, double duration, const String& scheduledDowntime = String(),
const String& scheduledBy = String(), const String& parent = String(), const String& id = String(),
const MessageOrigin::Ptr& origin = nullptr);

Expand Down
74 changes: 19 additions & 55 deletions lib/icinga/externalcommandprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -967,16 +967,12 @@ void ExternalCommandProcessor::ScheduleSvcDowntime(double, const std::vector<Str
if (!service)
BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule service downtime for non-existent service '" + arguments[1] + "' on host '" + arguments[0] + "'"));

String triggeredBy;
Downtime::Ptr triggeredBy;
int triggeredByLegacy = Convert::ToLong(arguments[5]);
int is_fixed = Convert::ToLong(arguments[4]);

if (triggeredByLegacy != 0) {
auto trigger (Downtime::GetDowntimeFromLegacyID(triggeredByLegacy));

if (trigger) {
triggeredBy = trigger->GetName();
}
triggeredBy = Downtime::GetDowntimeFromLegacyID(triggeredByLegacy);
}

Log(LogNotice, "ExternalCommandProcessor")
Expand Down Expand Up @@ -1013,16 +1009,12 @@ void ExternalCommandProcessor::ScheduleHostDowntime(double, const std::vector<St
if (!host)
BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule host downtime for non-existent host '" + arguments[0] + "'"));

String triggeredBy;
Downtime::Ptr triggeredBy;
int triggeredByLegacy = Convert::ToLong(arguments[4]);
int is_fixed = Convert::ToLong(arguments[3]);

if (triggeredByLegacy != 0) {
auto trigger (Downtime::GetDowntimeFromLegacyID(triggeredByLegacy));

if (trigger) {
triggeredBy = trigger->GetName();
}
triggeredBy = Downtime::GetDowntimeFromLegacyID(triggeredByLegacy);
}

Log(LogNotice, "ExternalCommandProcessor")
Expand All @@ -1040,16 +1032,12 @@ void ExternalCommandProcessor::ScheduleAndPropagateHostDowntime(double, const st
if (!host)
BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule and propagate host downtime for non-existent host '" + arguments[0] + "'"));

String triggeredBy;
Downtime::Ptr triggeredBy;
int triggeredByLegacy = Convert::ToLong(arguments[4]);
int is_fixed = Convert::ToLong(arguments[3]);

if (triggeredByLegacy != 0) {
auto trigger (Downtime::GetDowntimeFromLegacyID(triggeredByLegacy));

if (trigger) {
triggeredBy = trigger->GetName();
}
triggeredBy = Downtime::GetDowntimeFromLegacyID(triggeredByLegacy);
}

Log(LogNotice, "ExternalCommandProcessor")
Expand Down Expand Up @@ -1082,16 +1070,12 @@ void ExternalCommandProcessor::ScheduleAndPropagateTriggeredHostDowntime(double,
if (!host)
BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule and propagate triggered host downtime for non-existent host '" + arguments[0] + "'"));

String triggeredBy;
Downtime::Ptr triggeredBy;
int triggeredByLegacy = Convert::ToLong(arguments[4]);
int is_fixed = Convert::ToLong(arguments[3]);

if (triggeredByLegacy != 0) {
auto trigger (Downtime::GetDowntimeFromLegacyID(triggeredByLegacy));

if (trigger) {
triggeredBy = trigger->GetName();
}
triggeredBy = Downtime::GetDowntimeFromLegacyID(triggeredByLegacy);
}

Log(LogNotice, "ExternalCommandProcessor")
Expand All @@ -1113,7 +1097,7 @@ void ExternalCommandProcessor::ScheduleAndPropagateTriggeredHostDowntime(double,

(void) Downtime::AddDowntime(child, arguments[6], arguments[7],
Convert::ToDouble(arguments[1]), Convert::ToDouble(arguments[2]),
Convert::ToBool(is_fixed), parentDowntime->GetName(), Convert::ToDouble(arguments[5]));
Convert::ToBool(is_fixed), parentDowntime, Convert::ToDouble(arguments[5]));
}
}

Expand Down Expand Up @@ -1203,16 +1187,12 @@ void ExternalCommandProcessor::ScheduleHostSvcDowntime(double, const std::vector
if (!host)
BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule host services downtime for non-existent host '" + arguments[0] + "'"));

String triggeredBy;
Downtime::Ptr triggeredBy;
int triggeredByLegacy = Convert::ToLong(arguments[4]);
int is_fixed = Convert::ToLong(arguments[3]);

if (triggeredByLegacy != 0) {
auto trigger (Downtime::GetDowntimeFromLegacyID(triggeredByLegacy));

if (trigger) {
triggeredBy = trigger->GetName();
}
triggeredBy = Downtime::GetDowntimeFromLegacyID(triggeredByLegacy);
}

Log(LogNotice, "ExternalCommandProcessor")
Expand All @@ -1238,16 +1218,12 @@ void ExternalCommandProcessor::ScheduleHostgroupHostDowntime(double, const std::
if (!hg)
BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule hostgroup host downtime for non-existent hostgroup '" + arguments[0] + "'"));

String triggeredBy;
Downtime::Ptr triggeredBy;
int triggeredByLegacy = Convert::ToLong(arguments[4]);
int is_fixed = Convert::ToLong(arguments[3]);

if (triggeredByLegacy != 0) {
auto trigger (Downtime::GetDowntimeFromLegacyID(triggeredByLegacy));

if (trigger) {
triggeredBy = trigger->GetName();
}
triggeredBy = Downtime::GetDowntimeFromLegacyID(triggeredByLegacy);
}

for (const Host::Ptr& host : hg->GetMembers()) {
Expand All @@ -1267,16 +1243,12 @@ void ExternalCommandProcessor::ScheduleHostgroupSvcDowntime(double, const std::v
if (!hg)
BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule hostgroup service downtime for non-existent hostgroup '" + arguments[0] + "'"));

String triggeredBy;
Downtime::Ptr triggeredBy;
int triggeredByLegacy = Convert::ToLong(arguments[4]);
int is_fixed = Convert::ToLong(arguments[3]);

if (triggeredByLegacy != 0) {
auto trigger (Downtime::GetDowntimeFromLegacyID(triggeredByLegacy));

if (trigger) {
triggeredBy = trigger->GetName();
}
triggeredBy = Downtime::GetDowntimeFromLegacyID(triggeredByLegacy);
}

/* Note: we can't just directly create downtimes for all the services by iterating
Expand Down Expand Up @@ -1307,16 +1279,12 @@ void ExternalCommandProcessor::ScheduleServicegroupHostDowntime(double, const st
if (!sg)
BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule servicegroup host downtime for non-existent servicegroup '" + arguments[0] + "'"));

String triggeredBy;
Downtime::Ptr triggeredBy;
int triggeredByLegacy = Convert::ToLong(arguments[4]);
int is_fixed = Convert::ToLong(arguments[3]);

if (triggeredByLegacy != 0) {
auto trigger (Downtime::GetDowntimeFromLegacyID(triggeredByLegacy));

if (trigger) {
triggeredBy = trigger->GetName();
}
triggeredBy = Downtime::GetDowntimeFromLegacyID(triggeredByLegacy);
}

/* Note: we can't just directly create downtimes for all the hosts by iterating
Expand Down Expand Up @@ -1346,16 +1314,12 @@ void ExternalCommandProcessor::ScheduleServicegroupSvcDowntime(double, const std
if (!sg)
BOOST_THROW_EXCEPTION(std::invalid_argument("Cannot schedule servicegroup service downtime for non-existent servicegroup '" + arguments[0] + "'"));

String triggeredBy;
Downtime::Ptr triggeredBy;
int triggeredByLegacy = Convert::ToLong(arguments[4]);
int is_fixed = Convert::ToLong(arguments[3]);

if (triggeredByLegacy != 0) {
auto trigger (Downtime::GetDowntimeFromLegacyID(triggeredByLegacy));

if (trigger) {
triggeredBy = trigger->GetName();
}
triggeredBy = Downtime::GetDowntimeFromLegacyID(triggeredByLegacy);
}

for (const Service::Ptr& service : sg->GetMembers()) {
Expand Down
8 changes: 4 additions & 4 deletions lib/icinga/scheduleddowntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,17 +282,17 @@ void ScheduledDowntime::CreateNextDowntime()

Downtime::Ptr downtime = Downtime::AddDowntime(GetCheckable(), GetAuthor(), GetComment(),
segment.first, segment.second,
GetFixed(), String(), GetDuration(), GetName(), GetName());
GetFixed(), nullptr, GetDuration(), GetName(), GetName());
String downtimeName = downtime->GetName();

int childOptions = Downtime::ChildOptionsFromValue(GetChildOptions());
if (childOptions > 0) {
/* 'DowntimeTriggeredChildren' schedules child downtimes triggered by the parent downtime.
* 'DowntimeNonTriggeredChildren' schedules non-triggered downtimes for all children.
*/
String triggerName;
Downtime::Ptr trigger;
if (childOptions == 1)
triggerName = downtimeName;
trigger = downtime;

Log(LogNotice, "ScheduledDowntime")
<< "Processing child options " << childOptions << " for downtime " << downtimeName;
Expand All @@ -302,7 +302,7 @@ void ScheduledDowntime::CreateNextDowntime()
<< "Scheduling downtime for child object " << child->GetName();

Downtime::Ptr childDowntime = Downtime::AddDowntime(child, GetAuthor(), GetComment(),
segment.first, segment.second, GetFixed(), triggerName, GetDuration(), GetName(), GetName());
segment.first, segment.second, GetFixed(), trigger, GetDuration(), GetName(), GetName());

Log(LogNotice, "ScheduledDowntime")
<< "Add child downtime '" << childDowntime->GetName() << "'.";
Expand Down

0 comments on commit 58a10ad

Please sign in to comment.