qinling/qinling/utils/jobs.py

87 lines
2.6 KiB
Python

# Copyright 2017 Catalyst IT Limited
#
# 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.
import datetime
import croniter
from dateutil import parser
from oslo_utils import timeutils
import six
from qinling import exceptions as exc
def validate_next_time(next_execution_time):
next_time = next_execution_time
if isinstance(next_execution_time, six.string_types):
try:
# We need naive datetime object.
next_time = parser.parse(next_execution_time, ignoretz=True)
except ValueError as e:
raise exc.InputException(str(e))
valid_min_time = timeutils.utcnow() + datetime.timedelta(0, 60)
if valid_min_time > next_time:
raise exc.InputException(
'Execution time must be at least 1 minute in the future.'
)
return next_time
def validate_pattern(pattern):
try:
croniter.croniter(pattern)
except (ValueError, KeyError):
raise exc.InputException(
'The specified pattern is not valid: {}'.format(pattern)
)
def validate_job(params):
first_time = params.get('first_execution_time')
pattern = params.get('pattern')
count = params.get('count')
start_time = timeutils.utcnow()
if not (first_time or pattern):
raise exc.InputException(
'Pattern or first_execution_time must be specified.'
)
if first_time:
first_time = validate_next_time(first_time)
if not pattern and count and count > 1:
raise exc.InputException(
'Pattern must be provided if count is greater than 1.'
)
next_time = first_time
if not (pattern or count):
count = 1
if pattern:
validate_pattern(pattern)
if not first_time:
next_time = croniter.croniter(pattern, start_time).get_next(
datetime.datetime
)
return first_time, next_time, count
def get_next_execution_time(pattern, start_time):
return croniter.croniter(pattern, start_time).get_next(
datetime.datetime
)