}
%type TimePeriod %inherits CustomVarObject {
+ %validator "ValidateTimePeriodRanges",
+
%attribute %string "display_name",
%require "update",
String second = def.SubStr(pos + 1);
second.Trim();
- ParseTimeSpec(first, begin, NULL, reference);
+ try {
+ ParseTimeSpec(first, begin, NULL, reference);
+ } catch (std::exception&) {
+ throw;
+ }
/* If the second definition starts with a number we need
* to add the first word from the first definition, e.g.:
second = first.SubStr(0, xpos + 1) + second;
}
- ParseTimeSpec(second, NULL, end, reference);
+ try {
+ ParseTimeSpec(second, NULL, end, reference);
+ } catch (std::exception&) {
+ throw;
+ }
} else {
- ParseTimeSpec(def, begin, end, reference);
+ try {
+ ParseTimeSpec(def, begin, end, reference);
+ } catch (std::exception&) {
+ throw;
+ }
}
}
Dictionary::Ptr LegacyTimePeriod::ProcessTimeRange(const String& timestamp, tm *reference)
{
tm begin, end;
- ProcessTimeRangeRaw(timestamp, reference, &begin, &end);
+
+ try {
+ ProcessTimeRangeRaw(timestamp, reference, &begin, &end);
+ } catch (std::exception&) {
+ throw;
+ }
+
Dictionary::Ptr segment = new Dictionary();
segment->Set("begin", (long)mktime(&begin));
segment->Set("end", (long)mktime(&end));
boost::algorithm::split(ranges, timeranges, boost::is_any_of(","));
BOOST_FOREACH(const String& range, ranges) {
- Dictionary::Ptr segment = ProcessTimeRange(range, reference);
+ Dictionary::Ptr segment;
+ try {
+ segment = ProcessTimeRange(range, reference);
+ } catch (std::exception&) {
+ throw;
+ }
+
if (segment->Get("begin") >= segment->Get("end"))
BOOST_THROW_EXCEPTION(std::invalid_argument("Time period segment ends before it begins"));
******************************************************************************/
#include "icinga/timeperiod.hpp"
+#include "icinga/legacytimeperiod.hpp"
#include "base/dynamictype.hpp"
#include "base/objectlock.hpp"
+#include "base/exception.hpp"
#include "base/logger.hpp"
#include "base/timer.hpp"
#include "base/utility.hpp"
using namespace icinga;
REGISTER_TYPE(TimePeriod);
+REGISTER_SCRIPTFUNCTION(ValidateTimePeriodRanges, &TimePeriod::ValidateRanges);
static Timer::Ptr l_UpdateTimer;
Log(LogDebug, "TimePeriod", "---");
}
+
+void TimePeriod::ValidateRanges(const String& location, const TimePeriod::Ptr& object)
+{
+ Dictionary::Ptr ranges = object->GetRanges();
+
+ if (!ranges)
+ return;
+
+ /* create a fake time environment to validate the definitions */
+ time_t begin = Utility::GetTime();
+ time_t end = begin + 24 * 60 * 60;
+ tm reference = Utility::LocalTime(end);
+ tm begin_tm, end_tm;
+ Array::Ptr segments = new Array();
+
+ ObjectLock olock(ranges);
+ BOOST_FOREACH(const Dictionary::Pair& kv, ranges) {
+ try {
+ LegacyTimePeriod::ParseTimeSpec(kv.first, &begin_tm, &end_tm, &reference);
+ } catch (std::exception&) {
+ BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
+ location + ": Invalid time specification.", object->GetDebugInfo()));
+ }
+
+ try {
+ LegacyTimePeriod::ProcessTimeRanges(kv.second, &reference, segments);
+ } catch (std::exception&) {
+ BOOST_THROW_EXCEPTION(ScriptError("Validation failed for " +
+ location + ": Invalid time range definition.", object->GetDebugInfo()));
+ }
+ }
+}
bool IsInside(double ts) const;
double FindNextTransition(double begin);
+ static void ValidateRanges(const String& location, const TimePeriod::Ptr& object);
+
private:
void AddSegment(double s, double end);
void AddSegment(const Dictionary::Ptr& segment);