karbor/karbor/services/operationengine/engine/triggers/timetrigger/utils.py

124 lines
4.1 KiB
Python

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from datetime import datetime
from oslo_config import cfg
from oslo_utils import timeutils
import six
from stevedore import driver as import_driver
from karbor import exception
from karbor.i18n import _
CONF = cfg.CONF
def get_time_format_class():
return import_driver.DriverManager(
'karbor.operationengine.engine.timetrigger.time_format',
CONF.time_format).driver
def compute_next_run_time(start_time, end_time, timer):
next_time = timer.compute_next_time(start_time)
if next_time and (not end_time or next_time <= end_time):
return next_time
return None
def check_and_get_datetime(time, time_name):
if not time:
return None
if isinstance(time, datetime):
return time
if not isinstance(time, six.string_types):
msg = (_("The trigger %(name)s(type = %(vtype)s) is "
"not an instance of string") %
{"name": time_name, "vtype": type(time)})
raise exception.InvalidInput(msg)
try:
time = timeutils.parse_strtime(time, fmt='%Y-%m-%d %H:%M:%S')
except Exception:
msg = (_("The format of trigger %s is not correct") % time_name)
raise exception.InvalidInput(msg)
return time
def check_trigger_definition(trigger_definition):
"""Check trigger definition
All the time instances of trigger_definition are in UTC,
including start_time, end_time
"""
tf_cls = get_time_format_class()
pattern = trigger_definition.get("pattern", None)
tf_cls.check_time_format(pattern)
start_time = trigger_definition.get("start_time", None)
if not start_time:
msg = _("The trigger\'s start time is unknown")
raise exception.InvalidInput(msg)
start_time = check_and_get_datetime(start_time, "start_time")
interval = tf_cls(start_time, pattern).get_min_interval()
if interval is not None and interval < CONF.min_interval:
msg = (_("The interval of two adjacent time points "
"is less than %d") % CONF.min_interval)
raise exception.InvalidInput(msg)
window = trigger_definition.get("window", CONF.min_window_time)
if not isinstance(window, int):
try:
window = int(window)
except Exception:
msg = (_("The trigger windows(%s) is not integer") % window)
raise exception.InvalidInput(msg)
if window < CONF.min_window_time or window > CONF.max_window_time:
msg = (_("The trigger windows %(window)d must be between "
"%(min_window)d and %(max_window)d") %
{"window": window,
"min_window": CONF.min_window_time,
"max_window": CONF.max_window_time})
raise exception.InvalidInput(msg)
end_time = trigger_definition.get("end_time", None)
end_time = check_and_get_datetime(end_time, "end_time")
valid_trigger_property = trigger_definition.copy()
valid_trigger_property['window'] = window
valid_trigger_property['start_time'] = start_time
valid_trigger_property['end_time'] = end_time
return valid_trigger_property
def check_configuration():
min_window = CONF.min_window_time
max_window = CONF.max_window_time
min_interval = CONF.min_interval
if not (min_window < max_window and (max_window * 2 <= min_interval)):
msg = (_('Configurations of time trigger are invalid'))
raise exception.InvalidInput(msg)
def get_timer(trigger_property):
tf_cls = get_time_format_class()
timer = tf_cls(trigger_property['start_time'],
trigger_property['pattern'])
return timer