58
62
self.api_client = ceiloclient.get_client(2, **creds)
59
63
return self.api_client
61
def _refresh(self, alarm, state, reason):
65
def _refresh(self, alarm, state, reason, reason_data):
62
66
"""Refresh alarm state."""
64
68
previous = alarm.state
71
75
self._client.alarms.set_state(alarm.alarm_id, state=state)
72
76
alarm.state = state
74
self.notifier.notify(alarm, previous, reason)
78
self.notifier.notify(alarm, previous, reason, reason_data)
76
80
# retry will occur naturally on the next evaluation
77
81
# cycle (unless alarm state reverts in the meantime)
78
82
LOG.exception(_('alarm state update failed'))
85
def within_time_constraint(cls, alarm):
86
"""Check whether the alarm is within at least one of its time
87
constraints. If there are none, then the answer is yes.
89
if not alarm.time_constraints:
92
now_utc = timeutils.utcnow()
93
for tc in alarm.time_constraints:
94
tz = pytz.timezone(tc['timezone']) if tc['timezone'] else None
95
now_tz = now_utc.astimezone(tz) if tz else now_utc
96
start_cron = croniter.croniter(tc['start'], now_tz)
97
if cls._is_exact_match(start_cron, now_tz):
99
latest_start = start_cron.get_prev(datetime.datetime)
100
duration = datetime.timedelta(seconds=tc['duration'])
101
if latest_start <= now_tz <= latest_start + duration:
106
def _is_exact_match(cron, ts):
107
"""Handle edge case where if the timestamp is the same as the
108
cron point in time to the minute, croniter returns the previous
109
start, not the current. We can check this by first going one
110
step back and then one step forward and check if we are
111
at the original point in time.
114
diff = timeutils.total_seconds(ts - cron.get_next(datetime.datetime))
115
return abs(diff) < 60 # minute precision
80
117
@abc.abstractmethod
81
118
def evaluate(self, alarm):
82
119
'''interface definition